[NTOS]: Reimplement MmCreateProcessAddressSpace in ARM3. Basically the same as before but using the ARM3 PFN list APIs, the ARM3 macros, etc. Once change is processes are now populating the MmProcessList, and the "MmGlobalKernelPageTable" isn't used anymore for new processes. Also the mappings come from SysPTE space, not hyperspace.

[NTOS]: More work will be needed in this area, but this gets rid of another ReactOS dinosaur.

svn path=/trunk/; revision=48233
This commit is contained in:
Sir Richard 2010-07-24 15:30:24 +00:00
parent ecd26cf41a
commit 3ec9a11a16
4 changed files with 101 additions and 92 deletions

View file

@ -485,6 +485,7 @@ extern PMMPTE MiHighestUserPte;
extern PMMPDE MiHighestUserPde;
extern PFN_NUMBER MmSystemPageDirectory[PD_COUNT];
extern PMMPTE MmSharedUserDataPte;
extern LIST_ENTRY MmProcessList;
#define MI_PFN_TO_PFNENTRY(x) (&MmPfnDatabase[1][x])
#define MI_PFNENTRY_TO_PFN(x) (x - MmPfnDatabase[1])
@ -1031,6 +1032,12 @@ MiRemoveZeroPage(
IN ULONG Color
);
VOID
NTAPI
MiZeroPhysicalPage(
IN PFN_NUMBER PageFrameIndex
);
VOID
NTAPI
MiInsertPageInFreeList(

View file

@ -878,12 +878,12 @@ MmInitializeProcessAddressSpace(IN PEPROCESS Process,
/* Setup the PFN for the PDE base of this process */
PointerPte = MiAddressToPte(PDE_BASE);
PageFrameNumber = PFN_FROM_PTE(PointerPte);
//MiInitializePfn(PageFrameNumber, PointerPte, TRUE);
MiInitializePfn(PageFrameNumber, PointerPte, TRUE);
/* Do the same for hyperspace */
PointerPde = MiAddressToPde(HYPER_SPACE);
PageFrameNumber = PFN_FROM_PTE(PointerPde);
//MiInitializePfn(PageFrameNumber, PointerPde, TRUE);
MiInitializePfn(PageFrameNumber, PointerPde, TRUE);
/* Release PFN lock */
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
@ -991,6 +991,98 @@ MmInitializeHandBuiltProcess2(IN PEPROCESS Process)
return STATUS_SUCCESS;
}
/* FIXME: Evaluate ways to make this portable yet arch-specific */
BOOLEAN
NTAPI
MmCreateProcessAddressSpace(IN ULONG MinWs,
IN PEPROCESS Process,
OUT PULONG_PTR DirectoryTableBase)
{
KIRQL OldIrql;
PFN_NUMBER PdeIndex, HyperIndex;
PMMPTE PointerPte;
MMPTE TempPte, PdePte;
ULONG PdeOffset;
PMMPTE SystemTable;
/* No page colors yet */
Process->NextPageColor = 0;
/* Setup the hyperspace lock */
KeInitializeSpinLock(&Process->HyperSpaceLock);
/* Lock PFN database */
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
/* Get a page for the PDE */
PdeIndex = MiRemoveAnyPage(0);
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
MiZeroPhysicalPage(PdeIndex);
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
/* Get a page for hyperspace */
HyperIndex = MiRemoveAnyPage(0);
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
MiZeroPhysicalPage(HyperIndex);
/* Switch to phase 1 initialization */
ASSERT(Process->AddressSpaceInitialized == 0);
Process->AddressSpaceInitialized = 1;
/* Set the base directory pointers */
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);
/* Insert us into the Mm process list */
InsertTailList(&MmProcessList, &Process->MmProcessLinks);
/* 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 */
PdePte.u.Hard.Dirty = TRUE;
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 = ValidKernelPte;
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);
return TRUE;
}
/* SYSTEM CALLS ***************************************************************/
NTSTATUS

View file

@ -112,94 +112,6 @@ ProtectToPTE(ULONG flProtect)
return(Attributes);
}
NTSTATUS
NTAPI
Mmi386ReleaseMmInfo(PEPROCESS Process)
{
PUSHORT LdtDescriptor;
ULONG LdtBase;
PULONG PageDir;
ULONG i;
DPRINT("Mmi386ReleaseMmInfo(Process %x)\n",Process);
LdtDescriptor = (PUSHORT) &Process->Pcb.LdtDescriptor;
LdtBase = LdtDescriptor[1] |
((LdtDescriptor[2] & 0xff) << 16) |
((LdtDescriptor[3] & ~0xff) << 16);
DPRINT("LdtBase: %x\n", LdtBase);
if (LdtBase)
{
ExFreePool((PVOID) LdtBase);
}
PageDir = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0]));
for (i = 0; i < ADDR_TO_PDE_OFFSET(MmSystemRangeStart); i++)
{
if (PageDir[i] != 0)
{
MiZeroPage(PTE_TO_PFN(PageDir[i]));
MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PFN(PageDir[i]));
}
}
MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PFN(PageDir[ADDR_TO_PDE_OFFSET(HYPERSPACE)]));
MmDeleteHyperspaceMapping(PageDir);
MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0]));
Process->Pcb.DirectoryTableBase[0] = 0;
Process->Pcb.DirectoryTableBase[1] = 0;
DPRINT("Finished Mmi386ReleaseMmInfo()\n");
return(STATUS_SUCCESS);
}
BOOLEAN
NTAPI
MmCreateProcessAddressSpace(IN ULONG MinWs,
IN PEPROCESS Process,
IN PULONG DirectoryTableBase)
{
NTSTATUS Status;
ULONG i, j;
PFN_NUMBER Pfn[2];
PULONG PageDirectory;
DPRINT("MmCopyMmInfo(Src %x, Dest %x)\n", MinWs, Process);
for (i = 0; i < 2; i++)
{
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn[i]);
if (!NT_SUCCESS(Status))
{
for (j = 0; j < i; j++)
{
MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn[j]);
}
return FALSE;
}
}
PageDirectory = MmCreateHyperspaceMapping(Pfn[0]);
memcpy(PageDirectory + ADDR_TO_PDE_OFFSET(MmSystemRangeStart),
MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(MmSystemRangeStart),
(1024 - ADDR_TO_PDE_OFFSET(MmSystemRangeStart)) * sizeof(ULONG));
DPRINT("Addr %x\n",ADDR_TO_PDE_OFFSET(PAGETABLE_MAP));
PageDirectory[ADDR_TO_PDE_OFFSET(PAGETABLE_MAP)] = PFN_TO_PTE(Pfn[0]) | PA_PRESENT | PA_READWRITE;
PageDirectory[ADDR_TO_PDE_OFFSET(HYPERSPACE)] = PFN_TO_PTE(Pfn[1]) | PA_PRESENT | PA_READWRITE;
MmDeleteHyperspaceMapping(PageDirectory);
DirectoryTableBase[0] = PFN_TO_PTE(Pfn[0]);
DirectoryTableBase[1] = 0;
DPRINT("Finished MmCopyMmInfo(): 0x%x\n", DirectoryTableBase[0]);
return TRUE;
}
static PULONG
MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
{

View file

@ -61,8 +61,6 @@ MmDeleteProcessAddressSpace(PEPROCESS Process)
}
}
Mmi386ReleaseMmInfo(Process);
MmUnlockAddressSpace(&Process->Vm);
DPRINT("Finished MmReleaseMmInfo()\n");