Implement kernel stack allocation logic
This commit is contained in:
@@ -21,13 +21,12 @@ namespace MM
|
||||
STATIC UCHAR ProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE];
|
||||
|
||||
public:
|
||||
STATIC XTAPI XTSTATUS AllocateKernelStack(IN PVOID *Stack,
|
||||
IN BOOLEAN LargeStack,
|
||||
IN UCHAR SystemNode);
|
||||
STATIC XTAPI XTSTATUS AllocateKernelStack(OUT PVOID *Stack,
|
||||
IN ULONG StackSize);
|
||||
STATIC XTAPI XTSTATUS AllocateProcessorStructures(IN ULONG CpuNumber,
|
||||
OUT PVOID *StructuresData);
|
||||
OUT PVOID *StructuresData);
|
||||
STATIC XTAPI VOID FreeKernelStack(IN PVOID Stack,
|
||||
IN BOOLEAN LargeStack);
|
||||
IN ULONG StackSize);
|
||||
STATIC XTAPI VOID FreeProcessorStructures(IN PVOID StructuresData);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -27,12 +27,68 @@
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
MM::KernelPool::AllocateKernelStack(IN PVOID *Stack,
|
||||
IN BOOLEAN LargeStack,
|
||||
IN UCHAR SystemNode)
|
||||
MM::KernelPool::AllocateKernelStack(OUT PVOID *Stack,
|
||||
IN ULONG StackSize)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
PFN_COUNT StackPtes, StackPages;
|
||||
PMMPTE PointerPte, StackPte;
|
||||
MMPTE TempPte, InvalidPte;
|
||||
PFN_NUMBER PageFrameIndex;
|
||||
ULONG Index;
|
||||
|
||||
/* Initialize the output stack pointer to NULLPTR */
|
||||
*Stack = NULLPTR;
|
||||
|
||||
/* Convert the requested stack size into a page count */
|
||||
StackPtes = SIZE_TO_PAGES(StackSize);
|
||||
StackPages = StackPtes;
|
||||
|
||||
/* Reserve PTEs for the stack pages, plus a guard page */
|
||||
StackPte = MM::Pte::ReserveSystemPtes(StackPtes + 1, SystemPteSpace, 0);
|
||||
if(!StackPte)
|
||||
{
|
||||
/* Failed to reserve PTEs for the new kernel stack */
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Set up a template for an invalid PTE */
|
||||
MM::Paging::SetPte(&InvalidPte, 0, 0x18);
|
||||
|
||||
/* Set up a template for a valid, writable stack PTE */
|
||||
MM::Paging::ClearPte(&TempPte);
|
||||
MM::Paging::SetPte(&TempPte, 0, MM_PTE_READWRITE | MM_PTE_CACHE_ENABLE);
|
||||
|
||||
/* Acquire the PFN database lock and raise runlevel to DISPATCH_LEVEL */
|
||||
KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);
|
||||
KE::QueuedSpinLockGuard SpinLock(SystemSpaceLock);
|
||||
|
||||
/* Start iterating from the base of the reserved PTE block */
|
||||
PointerPte = StackPte;
|
||||
|
||||
/* Loop through each page of the stack that needs to be allocated */
|
||||
for(Index = 0; Index < StackPages; Index++)
|
||||
{
|
||||
/* Advance to the next PTE */
|
||||
PointerPte = MM::Paging::GetNextPte(PointerPte);
|
||||
|
||||
/* Allocate a physical page and temporarily mark the PTE as invalid */
|
||||
PageFrameIndex = MM::Pfn::AllocatePhysicalPage(MM::Colors::GetNextColor());
|
||||
*PointerPte = InvalidPte;
|
||||
|
||||
/* Associate the physical page with its corresponding PTE in the PFN database */
|
||||
MM::Pfn::LinkPfnToPte(PageFrameIndex, PointerPte, 1);
|
||||
|
||||
/* Make the PTE valid, mapping the virtual address to the physical page */
|
||||
MM::Paging::SetPte(&TempPte, PageFrameIndex, 0);
|
||||
*PointerPte = TempPte;
|
||||
}
|
||||
|
||||
/* Zero the newly allocated stack memory, skipping the guard page */
|
||||
RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(MM::Paging::GetNextPte(StackPte)), MM_PAGE_SIZE * StackPtes);
|
||||
|
||||
/* Return a pointer to the top of the new stack */
|
||||
*Stack = MM::Paging::GetPteVirtualAddress(MM::Paging::AdvancePte(StackPte, StackPtes + 1));
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,7 +152,7 @@ MM::KernelPool::AllocateProcessorStructures(IN ULONG CpuNumber,
|
||||
XTAPI
|
||||
VOID
|
||||
MM::KernelPool::FreeKernelStack(IN PVOID Stack,
|
||||
IN BOOLEAN LargeStack)
|
||||
IN ULONG StackSize)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user