mirror of
https://github.com/reactos/reactos.git
synced 2024-06-28 17:01:28 +00:00
[NTOS:MM] Split MmCreateProcessAddressSpace in two parts
Generic one and arch-specific one. Properly fail if we are out of resources. Restore a lost assert.
This commit is contained in:
parent
6c027d28f9
commit
7ea8312617
|
@ -1205,6 +1205,13 @@ MmDeleteVirtualMapping(
|
||||||
PPFN_NUMBER Page
|
PPFN_NUMBER Page
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* arch/procsup.c ************************************************************/
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
MiArchCreateProcessAddressSpace(
|
||||||
|
_In_ PEPROCESS Process,
|
||||||
|
_In_ PULONG_PTR DirectoryTableBase);
|
||||||
|
|
||||||
/* wset.c ********************************************************************/
|
/* wset.c ********************************************************************/
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -999,18 +999,24 @@ MmInitializeProcessAddressSpace(IN PEPROCESS Process,
|
||||||
/* Do the same for hyperspace */
|
/* Do the same for hyperspace */
|
||||||
PointerPde = MiAddressToPde((PVOID)HYPER_SPACE);
|
PointerPde = MiAddressToPde((PVOID)HYPER_SPACE);
|
||||||
PageFrameNumber = PFN_FROM_PTE(PointerPde);
|
PageFrameNumber = PFN_FROM_PTE(PointerPde);
|
||||||
//ASSERT(Process->Pcb.DirectoryTableBase[0] == PageFrameNumber * PAGE_SIZE); // we're not lucky
|
|
||||||
MiInitializePfn(PageFrameNumber, (PMMPTE)PointerPde, TRUE);
|
MiInitializePfn(PageFrameNumber, (PMMPTE)PointerPde, TRUE);
|
||||||
|
#if (_MI_PAGING_LEVELS == 2)
|
||||||
|
ASSERT(Process->Pcb.DirectoryTableBase[1] == PageFrameNumber * PAGE_SIZE);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (_MI_PAGING_LEVELS >= 3)
|
#if (_MI_PAGING_LEVELS >= 3)
|
||||||
PointerPpe = MiAddressToPpe((PVOID)HYPER_SPACE);
|
PointerPpe = MiAddressToPpe((PVOID)HYPER_SPACE);
|
||||||
PageFrameNumber = PFN_FROM_PTE(PointerPpe);
|
PageFrameNumber = PFN_FROM_PTE(PointerPpe);
|
||||||
MiInitializePfn(PageFrameNumber, PointerPpe, TRUE);
|
MiInitializePfn(PageFrameNumber, PointerPpe, TRUE);
|
||||||
|
#if (_MI_PAGING_LEVELS == 3)
|
||||||
|
ASSERT(Process->Pcb.DirectoryTableBase[1] == PageFrameNumber * PAGE_SIZE);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if (_MI_PAGING_LEVELS == 4)
|
#if (_MI_PAGING_LEVELS == 4)
|
||||||
PointerPxe = MiAddressToPxe((PVOID)HYPER_SPACE);
|
PointerPxe = MiAddressToPxe((PVOID)HYPER_SPACE);
|
||||||
PageFrameNumber = PFN_FROM_PTE(PointerPxe);
|
PageFrameNumber = PFN_FROM_PTE(PointerPxe);
|
||||||
MiInitializePfn(PageFrameNumber, PointerPxe, TRUE);
|
MiInitializePfn(PageFrameNumber, PointerPxe, TRUE);
|
||||||
|
ASSERT(Process->Pcb.DirectoryTableBase[1] == PageFrameNumber * PAGE_SIZE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Setup the PFN for the PTE for the working set */
|
/* Setup the PFN for the PTE for the working set */
|
||||||
|
@ -1149,8 +1155,6 @@ MmInitializeHandBuiltProcess2(IN PEPROCESS Process)
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _M_IX86
|
|
||||||
/* FIXME: Evaluate ways to make this portable yet arch-specific */
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
MmCreateProcessAddressSpace(IN ULONG MinWs,
|
MmCreateProcessAddressSpace(IN ULONG MinWs,
|
||||||
|
@ -1158,13 +1162,13 @@ MmCreateProcessAddressSpace(IN ULONG MinWs,
|
||||||
OUT PULONG_PTR DirectoryTableBase)
|
OUT PULONG_PTR DirectoryTableBase)
|
||||||
{
|
{
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
PFN_NUMBER PdeIndex, HyperIndex, WsListIndex;
|
PFN_NUMBER TableBaseIndex, HyperIndex, WsListIndex;
|
||||||
PMMPTE PointerPte;
|
|
||||||
MMPTE TempPte, PdePte;
|
|
||||||
ULONG PdeOffset;
|
|
||||||
PMMPTE SystemTable, HyperTable;
|
|
||||||
ULONG Color;
|
ULONG Color;
|
||||||
PMMPFN Pfn1;
|
|
||||||
|
/* Make sure we don't already have a page directory setup */
|
||||||
|
ASSERT(Process->Pcb.DirectoryTableBase[0] == 0);
|
||||||
|
ASSERT(Process->Pcb.DirectoryTableBase[1] == 0);
|
||||||
|
ASSERT(Process->WorkingSetPage == 0);
|
||||||
|
|
||||||
/* Choose a process color */
|
/* Choose a process color */
|
||||||
Process->NextPageColor = (USHORT)RtlRandom(&MmProcessColorSeed);
|
Process->NextPageColor = (USHORT)RtlRandom(&MmProcessColorSeed);
|
||||||
|
@ -1175,22 +1179,25 @@ MmCreateProcessAddressSpace(IN ULONG MinWs,
|
||||||
/* Lock PFN database */
|
/* Lock PFN database */
|
||||||
OldIrql = MiAcquirePfnLock();
|
OldIrql = MiAcquirePfnLock();
|
||||||
|
|
||||||
/* Get a zero page for the PDE, if possible */
|
/*
|
||||||
|
* Get a page for the table base, one for hyper space & one for the working set list.
|
||||||
|
* The PFNs for these pages will be initialized in MmInitializeProcessAddressSpace,
|
||||||
|
* when we are already attached to the process.
|
||||||
|
* The other pages (if any) are allocated in the arch-specific part.
|
||||||
|
*/
|
||||||
Color = MI_GET_NEXT_PROCESS_COLOR(Process);
|
Color = MI_GET_NEXT_PROCESS_COLOR(Process);
|
||||||
MI_SET_USAGE(MI_USAGE_PAGE_DIRECTORY);
|
MI_SET_USAGE(MI_USAGE_PAGE_DIRECTORY);
|
||||||
PdeIndex = MiRemoveZeroPageSafe(Color);
|
TableBaseIndex = MiRemoveZeroPageSafe(Color);
|
||||||
if (!PdeIndex)
|
if (!TableBaseIndex)
|
||||||
{
|
{
|
||||||
/* No zero pages, grab a free one */
|
/* No zero pages, grab a free one */
|
||||||
PdeIndex = MiRemoveAnyPage(Color);
|
TableBaseIndex = MiRemoveAnyPage(Color);
|
||||||
|
|
||||||
/* Zero it outside the PFN lock */
|
/* Zero it outside the PFN lock */
|
||||||
MiReleasePfnLock(OldIrql);
|
MiReleasePfnLock(OldIrql);
|
||||||
MiZeroPhysicalPage(PdeIndex);
|
MiZeroPhysicalPage(TableBaseIndex);
|
||||||
OldIrql = MiAcquirePfnLock();
|
OldIrql = MiAcquirePfnLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a zero page for hyperspace, if possible */
|
|
||||||
MI_SET_USAGE(MI_USAGE_PAGE_DIRECTORY);
|
MI_SET_USAGE(MI_USAGE_PAGE_DIRECTORY);
|
||||||
Color = MI_GET_NEXT_PROCESS_COLOR(Process);
|
Color = MI_GET_NEXT_PROCESS_COLOR(Process);
|
||||||
HyperIndex = MiRemoveZeroPageSafe(Color);
|
HyperIndex = MiRemoveZeroPageSafe(Color);
|
||||||
|
@ -1204,8 +1211,6 @@ MmCreateProcessAddressSpace(IN ULONG MinWs,
|
||||||
MiZeroPhysicalPage(HyperIndex);
|
MiZeroPhysicalPage(HyperIndex);
|
||||||
OldIrql = MiAcquirePfnLock();
|
OldIrql = MiAcquirePfnLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a zero page for the woring set list, if possible */
|
|
||||||
MI_SET_USAGE(MI_USAGE_PAGE_TABLE);
|
MI_SET_USAGE(MI_USAGE_PAGE_TABLE);
|
||||||
Color = MI_GET_NEXT_PROCESS_COLOR(Process);
|
Color = MI_GET_NEXT_PROCESS_COLOR(Process);
|
||||||
WsListIndex = MiRemoveZeroPageSafe(Color);
|
WsListIndex = MiRemoveZeroPageSafe(Color);
|
||||||
|
@ -1224,99 +1229,33 @@ MmCreateProcessAddressSpace(IN ULONG MinWs,
|
||||||
MiReleasePfnLock(OldIrql);
|
MiReleasePfnLock(OldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set the base directory pointers */
|
||||||
|
Process->WorkingSetPage = WsListIndex;
|
||||||
|
DirectoryTableBase[0] = TableBaseIndex << PAGE_SHIFT;
|
||||||
|
DirectoryTableBase[1] = HyperIndex << PAGE_SHIFT;
|
||||||
|
|
||||||
|
/* Perform the arch-specific parts */
|
||||||
|
if (!MiArchCreateProcessAddressSpace(Process, DirectoryTableBase))
|
||||||
|
{
|
||||||
|
OldIrql = MiAcquirePfnLock();
|
||||||
|
MiInsertPageInFreeList(WsListIndex);
|
||||||
|
MiInsertPageInFreeList(HyperIndex);
|
||||||
|
MiInsertPageInFreeList(TableBaseIndex);
|
||||||
|
MiReleasePfnLock(OldIrql);
|
||||||
|
Process->WorkingSetPage = 0;
|
||||||
|
DirectoryTableBase[0] = 0;
|
||||||
|
DirectoryTableBase[1] = 0;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Switch to phase 1 initialization */
|
/* Switch to phase 1 initialization */
|
||||||
ASSERT(Process->AddressSpaceInitialized == 0);
|
ASSERT(Process->AddressSpaceInitialized == 0);
|
||||||
Process->AddressSpaceInitialized = 1;
|
Process->AddressSpaceInitialized = 1;
|
||||||
|
|
||||||
/* Set the base directory pointers */
|
|
||||||
Process->WorkingSetPage = WsListIndex;
|
|
||||||
DirectoryTableBase[0] = PdeIndex << PAGE_SHIFT;
|
|
||||||
DirectoryTableBase[1] = HyperIndex << PAGE_SHIFT;
|
|
||||||
|
|
||||||
/* Make sure we don't already have a page directory setup */
|
|
||||||
ASSERT(Process->Pcb.DirectoryTableBase[0] == 0);
|
|
||||||
|
|
||||||
/* Get a PTE to map hyperspace */
|
|
||||||
PointerPte = MiReserveSystemPtes(1, SystemPteSpace);
|
|
||||||
ASSERT(PointerPte != NULL);
|
|
||||||
|
|
||||||
/* Build it */
|
|
||||||
MI_MAKE_HARDWARE_PTE_KERNEL(&PdePte,
|
|
||||||
PointerPte,
|
|
||||||
MM_READWRITE,
|
|
||||||
HyperIndex);
|
|
||||||
|
|
||||||
/* Set it dirty and map it */
|
|
||||||
MI_MAKE_DIRTY_PAGE(&PdePte);
|
|
||||||
MI_WRITE_VALID_PTE(PointerPte, PdePte);
|
|
||||||
|
|
||||||
/* Now get hyperspace's page table */
|
|
||||||
HyperTable = MiPteToAddress(PointerPte);
|
|
||||||
|
|
||||||
/* Now write the PTE/PDE entry for the working set list index itself */
|
|
||||||
TempPte = ValidKernelPteLocal;
|
|
||||||
TempPte.u.Hard.PageFrameNumber = WsListIndex;
|
|
||||||
PdeOffset = MiAddressToPteOffset(MmWorkingSetList);
|
|
||||||
HyperTable[PdeOffset] = TempPte;
|
|
||||||
|
|
||||||
/* Let go of the system PTE */
|
|
||||||
MiReleaseSystemPtes(PointerPte, 1, SystemPteSpace);
|
|
||||||
|
|
||||||
/* Save the PTE address of the page directory itself */
|
|
||||||
Pfn1 = MiGetPfnEntry(PdeIndex);
|
|
||||||
Pfn1->PteAddress = (PMMPTE)PDE_BASE;
|
|
||||||
|
|
||||||
/* Insert us into the Mm process list */
|
|
||||||
OldIrql = MiAcquireExpansionLock();
|
|
||||||
InsertTailList(&MmProcessList, &Process->MmProcessLinks);
|
|
||||||
MiReleaseExpansionLock(OldIrql);
|
|
||||||
|
|
||||||
/* Get a PTE to map the page directory */
|
|
||||||
PointerPte = MiReserveSystemPtes(1, SystemPteSpace);
|
|
||||||
ASSERT(PointerPte != NULL);
|
|
||||||
|
|
||||||
/* Build it */
|
|
||||||
MI_MAKE_HARDWARE_PTE_KERNEL(&PdePte,
|
|
||||||
PointerPte,
|
|
||||||
MM_READWRITE,
|
|
||||||
PdeIndex);
|
|
||||||
|
|
||||||
/* Set it dirty and map it */
|
|
||||||
MI_MAKE_DIRTY_PAGE(&PdePte);
|
|
||||||
MI_WRITE_VALID_PTE(PointerPte, PdePte);
|
|
||||||
|
|
||||||
/* Now get the page directory (which we'll double map, so call it a page table */
|
|
||||||
SystemTable = MiPteToAddress(PointerPte);
|
|
||||||
|
|
||||||
/* Copy all the kernel mappings */
|
|
||||||
PdeOffset = MiGetPdeOffset(MmSystemRangeStart);
|
|
||||||
RtlCopyMemory(&SystemTable[PdeOffset],
|
|
||||||
MiAddressToPde(MmSystemRangeStart),
|
|
||||||
PAGE_SIZE - PdeOffset * sizeof(MMPTE));
|
|
||||||
|
|
||||||
/* Now write the PTE/PDE entry for hyperspace itself */
|
|
||||||
TempPte = ValidKernelPteLocal;
|
|
||||||
TempPte.u.Hard.PageFrameNumber = HyperIndex;
|
|
||||||
PdeOffset = MiGetPdeOffset(HYPER_SPACE);
|
|
||||||
SystemTable[PdeOffset] = TempPte;
|
|
||||||
|
|
||||||
/* Sanity check */
|
|
||||||
PdeOffset++;
|
|
||||||
ASSERT(MiGetPdeOffset(MmHyperSpaceEnd) >= PdeOffset);
|
|
||||||
|
|
||||||
/* Now do the x86 trick of making the PDE a page table itself */
|
|
||||||
PdeOffset = MiGetPdeOffset(PTE_BASE);
|
|
||||||
TempPte.u.Hard.PageFrameNumber = PdeIndex;
|
|
||||||
SystemTable[PdeOffset] = TempPte;
|
|
||||||
|
|
||||||
/* Let go of the system PTE */
|
|
||||||
MiReleaseSystemPtes(PointerPte, 1, SystemPteSpace);
|
|
||||||
|
|
||||||
/* Add the process to the session */
|
/* Add the process to the session */
|
||||||
MiSessionAddProcess(Process);
|
MiSessionAddProcess(Process);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
|
|
|
@ -618,135 +618,4 @@ MmCreateVirtualMapping(PEPROCESS Process,
|
||||||
return MmCreateVirtualMappingUnsafe(Process, Address, Protect, Pages, PageCount);
|
return MmCreateVirtualMappingUnsafe(Process, Address, Protect, Pages, PageCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
|
||||||
NTAPI
|
|
||||||
MmCreateProcessAddressSpace(IN ULONG MinWs,
|
|
||||||
IN PEPROCESS Process,
|
|
||||||
OUT PULONG_PTR DirectoryTableBase)
|
|
||||||
{
|
|
||||||
KIRQL OldIrql;
|
|
||||||
PFN_NUMBER TableBasePfn, HyperPfn, HyperPdPfn, HyperPtPfn, WorkingSetPfn;
|
|
||||||
PMMPTE SystemPte;
|
|
||||||
MMPTE TempPte, PdePte;
|
|
||||||
ULONG TableIndex;
|
|
||||||
PMMPTE PageTablePointer;
|
|
||||||
|
|
||||||
/* Make sure we don't already have a page directory setup */
|
|
||||||
ASSERT(Process->Pcb.DirectoryTableBase[0] == 0);
|
|
||||||
ASSERT(Process->Pcb.DirectoryTableBase[1] == 0);
|
|
||||||
ASSERT(Process->WorkingSetPage == 0);
|
|
||||||
|
|
||||||
/* Choose a process color */
|
|
||||||
Process->NextPageColor = (USHORT)RtlRandom(&MmProcessColorSeed);
|
|
||||||
|
|
||||||
/* Setup the hyperspace lock */
|
|
||||||
KeInitializeSpinLock(&Process->HyperSpaceLock);
|
|
||||||
|
|
||||||
/* Lock PFN database */
|
|
||||||
OldIrql = MiAcquirePfnLock();
|
|
||||||
|
|
||||||
/* Get a page for the table base and one for hyper space. The PFNs for
|
|
||||||
these pages will be initialized in MmInitializeProcessAddressSpace,
|
|
||||||
when we are already attached to the process. */
|
|
||||||
TableBasePfn = MiRemoveAnyPage(MI_GET_NEXT_PROCESS_COLOR(Process));
|
|
||||||
HyperPfn = MiRemoveAnyPage(MI_GET_NEXT_PROCESS_COLOR(Process));
|
|
||||||
HyperPdPfn = MiRemoveAnyPage(MI_GET_NEXT_PROCESS_COLOR(Process));
|
|
||||||
HyperPtPfn = MiRemoveAnyPage(MI_GET_NEXT_PROCESS_COLOR(Process));
|
|
||||||
WorkingSetPfn = MiRemoveAnyPage(MI_GET_NEXT_PROCESS_COLOR(Process));
|
|
||||||
|
|
||||||
/* Release PFN lock */
|
|
||||||
MiReleasePfnLock(OldIrql);
|
|
||||||
|
|
||||||
/* Zero pages */
|
|
||||||
MiZeroPhysicalPage(TableBasePfn);
|
|
||||||
MiZeroPhysicalPage(HyperPfn);
|
|
||||||
MiZeroPhysicalPage(HyperPdPfn);
|
|
||||||
MiZeroPhysicalPage(HyperPtPfn);
|
|
||||||
MiZeroPhysicalPage(WorkingSetPfn);
|
|
||||||
|
|
||||||
/* Set the base directory pointers */
|
|
||||||
Process->WorkingSetPage = WorkingSetPfn;
|
|
||||||
DirectoryTableBase[0] = TableBasePfn << PAGE_SHIFT;
|
|
||||||
DirectoryTableBase[1] = HyperPfn << PAGE_SHIFT;
|
|
||||||
|
|
||||||
/* Get a PTE to map the page directory */
|
|
||||||
SystemPte = MiReserveSystemPtes(1, SystemPteSpace);
|
|
||||||
ASSERT(SystemPte != NULL);
|
|
||||||
|
|
||||||
/* Get its address */
|
|
||||||
PageTablePointer = MiPteToAddress(SystemPte);
|
|
||||||
|
|
||||||
/* Build the PTE for the page directory and map it */
|
|
||||||
PdePte = ValidKernelPte;
|
|
||||||
PdePte.u.Hard.PageFrameNumber = TableBasePfn;
|
|
||||||
*SystemPte = PdePte;
|
|
||||||
|
|
||||||
/// architecture specific
|
|
||||||
//MiInitializePageDirectoryForProcess(
|
|
||||||
|
|
||||||
/* Copy the kernel mappings and zero out the rest */
|
|
||||||
TableIndex = PXE_PER_PAGE / 2;
|
|
||||||
RtlZeroMemory(PageTablePointer, TableIndex * sizeof(MMPTE));
|
|
||||||
RtlCopyMemory(PageTablePointer + TableIndex,
|
|
||||||
MiAddressToPxe(0) + TableIndex,
|
|
||||||
PAGE_SIZE - TableIndex * sizeof(MMPTE));
|
|
||||||
|
|
||||||
/* Sanity check */
|
|
||||||
ASSERT(MiAddressToPxi(MmHyperSpaceEnd) >= TableIndex);
|
|
||||||
|
|
||||||
/* Setup a PTE for the page directory mappings */
|
|
||||||
TempPte = ValidKernelPte;
|
|
||||||
|
|
||||||
/* Update the self mapping of the PML4 */
|
|
||||||
TableIndex = MiAddressToPxi((PVOID)PXE_SELFMAP);
|
|
||||||
TempPte.u.Hard.PageFrameNumber = TableBasePfn;
|
|
||||||
PageTablePointer[TableIndex] = TempPte;
|
|
||||||
|
|
||||||
/* Write the PML4 entry for hyperspace */
|
|
||||||
TableIndex = MiAddressToPxi((PVOID)HYPER_SPACE);
|
|
||||||
TempPte.u.Hard.PageFrameNumber = HyperPfn;
|
|
||||||
PageTablePointer[TableIndex] = TempPte;
|
|
||||||
|
|
||||||
/* Map the hyperspace PDPT to the system PTE */
|
|
||||||
PdePte.u.Hard.PageFrameNumber = HyperPfn;
|
|
||||||
*SystemPte = PdePte;
|
|
||||||
__invlpg(PageTablePointer);
|
|
||||||
|
|
||||||
/* Write the hyperspace entry for the first PD */
|
|
||||||
TempPte.u.Hard.PageFrameNumber = HyperPdPfn;
|
|
||||||
PageTablePointer[0] = TempPte;
|
|
||||||
|
|
||||||
/* Map the hyperspace PD to the system PTE */
|
|
||||||
PdePte.u.Hard.PageFrameNumber = HyperPdPfn;
|
|
||||||
*SystemPte = PdePte;
|
|
||||||
__invlpg(PageTablePointer);
|
|
||||||
|
|
||||||
/* Write the hyperspace entry for the first PT */
|
|
||||||
TempPte.u.Hard.PageFrameNumber = HyperPtPfn;
|
|
||||||
PageTablePointer[0] = TempPte;
|
|
||||||
|
|
||||||
/* Map the hyperspace PT to the system PTE */
|
|
||||||
PdePte.u.Hard.PageFrameNumber = HyperPtPfn;
|
|
||||||
*SystemPte = PdePte;
|
|
||||||
__invlpg(PageTablePointer);
|
|
||||||
|
|
||||||
/* Write the hyperspace PTE for the working set list index */
|
|
||||||
TempPte.u.Hard.PageFrameNumber = WorkingSetPfn;
|
|
||||||
TableIndex = MiAddressToPti(MmWorkingSetList);
|
|
||||||
PageTablePointer[TableIndex] = TempPte;
|
|
||||||
|
|
||||||
/// end architecture specific
|
|
||||||
|
|
||||||
/* Release the system PTE */
|
|
||||||
MiReleaseSystemPtes(SystemPte, 1, SystemPteSpace);
|
|
||||||
|
|
||||||
/* Switch to phase 1 initialization */
|
|
||||||
ASSERT(Process->AddressSpaceInitialized == 0);
|
|
||||||
Process->AddressSpaceInitialized = 1;
|
|
||||||
|
|
||||||
/* Add the process to the session */
|
|
||||||
MiSessionAddProcess(Process);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
132
ntoskrnl/mm/amd64/procsup.c
Normal file
132
ntoskrnl/mm/amd64/procsup.c
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: GPL, See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* FILE: ntoskrnl/mm/amd64/procsup.c
|
||||||
|
* PURPOSE: Low level memory managment manipulation
|
||||||
|
*
|
||||||
|
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||||
|
* ReactOS Portable Systems Group
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *******************************************************************/
|
||||||
|
|
||||||
|
#include <ntoskrnl.h>
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#define MODULE_INVOLVED_IN_ARM3
|
||||||
|
#include <mm/ARM3/miarm.h>
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
MiArchCreateProcessAddressSpace(
|
||||||
|
_In_ PEPROCESS Process,
|
||||||
|
_In_ PULONG_PTR DirectoryTableBase)
|
||||||
|
{
|
||||||
|
KIRQL OldIrql;
|
||||||
|
PFN_NUMBER TableBasePfn, HyperPfn, HyperPdPfn, HyperPtPfn;
|
||||||
|
PMMPTE SystemPte;
|
||||||
|
MMPTE TempPte, PdePte;
|
||||||
|
ULONG TableIndex;
|
||||||
|
PMMPTE PageTablePointer;
|
||||||
|
ULONG PageColor;
|
||||||
|
|
||||||
|
/* Non-arch specific code-path allocated those for us */
|
||||||
|
TableBasePfn = DirectoryTableBase[0] >> PAGE_SHIFT;
|
||||||
|
HyperPfn = DirectoryTableBase[1] >> PAGE_SHIFT;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lock PFN database. Try getting zero pages.
|
||||||
|
* If that doesn't work, we take the slow path
|
||||||
|
* outside of the PFN lock.
|
||||||
|
*/
|
||||||
|
OldIrql = MiAcquirePfnLock();
|
||||||
|
PageColor = MI_GET_NEXT_PROCESS_COLOR(Process);
|
||||||
|
HyperPdPfn = MiRemoveZeroPageSafe(PageColor);
|
||||||
|
if(!HyperPdPfn)
|
||||||
|
{
|
||||||
|
HyperPdPfn = MiRemoveAnyPage(PageColor);
|
||||||
|
MiReleasePfnLock(OldIrql);
|
||||||
|
MiZeroPhysicalPage(HyperPdPfn);
|
||||||
|
OldIrql = MiAcquirePfnLock();
|
||||||
|
}
|
||||||
|
PageColor = MI_GET_NEXT_PROCESS_COLOR(Process);
|
||||||
|
HyperPtPfn = MiRemoveZeroPageSafe(PageColor);
|
||||||
|
if(!HyperPtPfn)
|
||||||
|
{
|
||||||
|
HyperPtPfn = MiRemoveAnyPage(PageColor);
|
||||||
|
MiReleasePfnLock(OldIrql);
|
||||||
|
MiZeroPhysicalPage(HyperPtPfn);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MiReleasePfnLock(OldIrql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a PTE to map the page directory */
|
||||||
|
SystemPte = MiReserveSystemPtes(1, SystemPteSpace);
|
||||||
|
if (!SystemPte)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Get its address */
|
||||||
|
PageTablePointer = MiPteToAddress(SystemPte);
|
||||||
|
|
||||||
|
/* Build the PTE for the page directory and map it */
|
||||||
|
MI_MAKE_HARDWARE_PTE_KERNEL(&PdePte, SystemPte, MM_READWRITE, TableBasePfn);
|
||||||
|
MI_WRITE_VALID_PTE(SystemPte, PdePte);
|
||||||
|
|
||||||
|
/* Copy the kernel mappings and zero out the rest */
|
||||||
|
TableIndex = PXE_PER_PAGE / 2;
|
||||||
|
RtlZeroMemory(PageTablePointer, TableIndex * sizeof(MMPTE));
|
||||||
|
RtlCopyMemory(PageTablePointer + TableIndex,
|
||||||
|
MiAddressToPxe(0) + TableIndex,
|
||||||
|
PAGE_SIZE - TableIndex * sizeof(MMPTE));
|
||||||
|
|
||||||
|
/* Sanity check */
|
||||||
|
ASSERT(MiAddressToPxi(MmHyperSpaceEnd) >= TableIndex);
|
||||||
|
|
||||||
|
/* Setup a PTE for the page directory mappings */
|
||||||
|
TempPte = ValidKernelPte;
|
||||||
|
|
||||||
|
/* Update the self mapping of the PML4 */
|
||||||
|
TableIndex = MiAddressToPxi((PVOID)PXE_SELFMAP);
|
||||||
|
TempPte.u.Hard.PageFrameNumber = TableBasePfn;
|
||||||
|
PageTablePointer[TableIndex] = TempPte;
|
||||||
|
|
||||||
|
/* Write the PML4 entry for hyperspace */
|
||||||
|
TableIndex = MiAddressToPxi((PVOID)HYPER_SPACE);
|
||||||
|
TempPte.u.Hard.PageFrameNumber = HyperPfn;
|
||||||
|
PageTablePointer[TableIndex] = TempPte;
|
||||||
|
|
||||||
|
/* Map the hyperspace PDPT to the system PTE */
|
||||||
|
PdePte.u.Hard.PageFrameNumber = HyperPfn;
|
||||||
|
*SystemPte = PdePte;
|
||||||
|
__invlpg(PageTablePointer);
|
||||||
|
|
||||||
|
/* Write the hyperspace entry for the first PD */
|
||||||
|
TempPte.u.Hard.PageFrameNumber = HyperPdPfn;
|
||||||
|
PageTablePointer[0] = TempPte;
|
||||||
|
|
||||||
|
/* Map the hyperspace PD to the system PTE */
|
||||||
|
PdePte.u.Hard.PageFrameNumber = HyperPdPfn;
|
||||||
|
*SystemPte = PdePte;
|
||||||
|
__invlpg(PageTablePointer);
|
||||||
|
|
||||||
|
/* Write the hyperspace entry for the first PT */
|
||||||
|
TempPte.u.Hard.PageFrameNumber = HyperPtPfn;
|
||||||
|
PageTablePointer[0] = TempPte;
|
||||||
|
|
||||||
|
/* Map the hyperspace PT to the system PTE */
|
||||||
|
PdePte.u.Hard.PageFrameNumber = HyperPtPfn;
|
||||||
|
*SystemPte = PdePte;
|
||||||
|
__invlpg(PageTablePointer);
|
||||||
|
|
||||||
|
/* Write the hyperspace PTE for the working set list index */
|
||||||
|
TempPte.u.Hard.PageFrameNumber = Process->WorkingSetPage;
|
||||||
|
TableIndex = MiAddressToPti(MmWorkingSetList);
|
||||||
|
PageTablePointer[TableIndex] = TempPte;
|
||||||
|
|
||||||
|
/* Release the system PTE */
|
||||||
|
MiReleaseSystemPtes(SystemPte, 1, SystemPteSpace);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
98
ntoskrnl/mm/i386/procsup.c
Normal file
98
ntoskrnl/mm/i386/procsup.c
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Kernel
|
||||||
|
* LICENSE: BSD-3-Clause (https://spdx.org/licenses/BSD-3-Clause.html)
|
||||||
|
* FILE: ntoskrnl/mm/i386/procsup.c
|
||||||
|
* PURPOSE: Process handling for i386 architecture
|
||||||
|
* PROGRAMMERS: Jérôme Gardou
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *******************************************************************/
|
||||||
|
|
||||||
|
#include <ntoskrnl.h>
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#define MODULE_INVOLVED_IN_ARM3
|
||||||
|
#include <mm/ARM3/miarm.h>
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
MiArchCreateProcessAddressSpace(
|
||||||
|
_In_ PEPROCESS Process,
|
||||||
|
_In_ PULONG_PTR DirectoryTableBase)
|
||||||
|
{
|
||||||
|
PFN_NUMBER PdeIndex = DirectoryTableBase[0] >> PAGE_SHIFT;
|
||||||
|
PFN_NUMBER HyperIndex = DirectoryTableBase[1] >> PAGE_SHIFT;
|
||||||
|
PMMPTE PointerPte;
|
||||||
|
MMPTE PdePte, TempPte;
|
||||||
|
PMMPTE PteTable;
|
||||||
|
ULONG PdeOffset;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
|
/* Get a PTE */
|
||||||
|
PointerPte = MiReserveSystemPtes(1, SystemPteSpace);
|
||||||
|
if (!PointerPte)
|
||||||
|
return FALSE;
|
||||||
|
PteTable = MiPteToAddress(PointerPte);
|
||||||
|
|
||||||
|
/* Build a page table for hyper space */
|
||||||
|
MI_MAKE_HARDWARE_PTE_KERNEL(&PdePte,
|
||||||
|
PointerPte,
|
||||||
|
MM_READWRITE,
|
||||||
|
HyperIndex);
|
||||||
|
|
||||||
|
/* Set it dirty and map it */
|
||||||
|
MI_MAKE_DIRTY_PAGE(&PdePte);
|
||||||
|
MI_WRITE_VALID_PTE(PointerPte, PdePte);
|
||||||
|
|
||||||
|
/* Now write the PTE/PDE entry for the working set list index itself */
|
||||||
|
TempPte = ValidKernelPteLocal;
|
||||||
|
TempPte.u.Hard.PageFrameNumber = Process->WorkingSetPage;
|
||||||
|
PdeOffset = MiAddressToPteOffset(MmWorkingSetList);
|
||||||
|
PteTable[PdeOffset] = TempPte;
|
||||||
|
|
||||||
|
/* Now we map the page directory */
|
||||||
|
MI_MAKE_HARDWARE_PTE_KERNEL(&PdePte,
|
||||||
|
PointerPte,
|
||||||
|
MM_READWRITE,
|
||||||
|
PdeIndex);
|
||||||
|
|
||||||
|
/* Set it dirty and map it */
|
||||||
|
MI_MAKE_DIRTY_PAGE(&PdePte);
|
||||||
|
*PointerPte = PdePte;
|
||||||
|
/* We changed the page! */
|
||||||
|
__invlpg(PteTable);
|
||||||
|
|
||||||
|
/* Now get the page directory (which we'll double map, so call it a page table) */
|
||||||
|
PteTable = MiPteToAddress(PointerPte);
|
||||||
|
|
||||||
|
/* Copy all the kernel mappings */
|
||||||
|
PdeOffset = MiGetPdeOffset(MmSystemRangeStart);
|
||||||
|
RtlCopyMemory(&PteTable[PdeOffset],
|
||||||
|
MiAddressToPde(MmSystemRangeStart),
|
||||||
|
PAGE_SIZE - PdeOffset * sizeof(MMPTE));
|
||||||
|
|
||||||
|
/* Now write the PTE/PDE entry for hyperspace itself */
|
||||||
|
TempPte = ValidKernelPteLocal;
|
||||||
|
TempPte.u.Hard.PageFrameNumber = HyperIndex;
|
||||||
|
PdeOffset = MiGetPdeOffset(HYPER_SPACE);
|
||||||
|
PteTable[PdeOffset] = TempPte;
|
||||||
|
|
||||||
|
/* Sanity check */
|
||||||
|
PdeOffset++;
|
||||||
|
ASSERT(MiGetPdeOffset(MmHyperSpaceEnd) >= PdeOffset);
|
||||||
|
|
||||||
|
/* Now do the x86 trick of making the PDE a page table itself */
|
||||||
|
PdeOffset = MiGetPdeOffset(PTE_BASE);
|
||||||
|
TempPte.u.Hard.PageFrameNumber = PdeIndex;
|
||||||
|
PteTable[PdeOffset] = TempPte;
|
||||||
|
|
||||||
|
/* Let go of the system PTE */
|
||||||
|
MiReleaseSystemPtes(PointerPte, 1, SystemPteSpace);
|
||||||
|
|
||||||
|
/* Insert us into the Mm process list */
|
||||||
|
OldIrql = MiAcquireExpansionLock();
|
||||||
|
InsertTailList(&MmProcessList, &Process->MmProcessLinks);
|
||||||
|
MiReleaseExpansionLock(OldIrql);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
|
@ -314,6 +314,7 @@ if(ARCH STREQUAL "i386")
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/i386/usercall.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/i386/usercall.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/i386/v86vdm.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/i386/v86vdm.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/mm/i386/page.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/mm/i386/page.c
|
||||||
|
${REACTOS_SOURCE_DIR}/ntoskrnl/mm/i386/procsup.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/mm/ARM3/i386/init.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/mm/ARM3/i386/init.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ps/i386/psctx.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/ps/i386/psctx.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ps/i386/psldt.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/ps/i386/psldt.c
|
||||||
|
@ -339,6 +340,7 @@ elseif(ARCH STREQUAL "amd64")
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/thrdini.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/thrdini.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/mm/amd64/init.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/mm/amd64/init.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/mm/amd64/page.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/mm/amd64/page.c
|
||||||
|
${REACTOS_SOURCE_DIR}/ntoskrnl/mm/amd64/procsup.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ps/amd64/psctx.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/ps/amd64/psctx.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/stubs.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/stubs.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/usercall.c)
|
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/usercall.c)
|
||||||
|
|
Loading…
Reference in a new issue