From 3e04cabe4eceb72c51d4ce658b7e86aeab86ec98 Mon Sep 17 00:00:00 2001 From: ReactOS Portable Systems Group Date: Mon, 27 Jul 2009 02:13:19 +0000 Subject: [PATCH] - Create a double-mapping PTE for the shared user data region and fault it in whenever a process touches that address. - Remove the old hack which used the PCR's page frame number to create a fake PTE each time to reference it, basing on the fact that the shared user data region was on the same page as the PCR on certain architectures. svn path=/trunk/; revision=42252 --- reactos/ntoskrnl/mm/mmfault.c | 12 +++--------- reactos/ntoskrnl/mm/mminit.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/reactos/ntoskrnl/mm/mmfault.c b/reactos/ntoskrnl/mm/mmfault.c index 490e77c314c..c954b07498e 100644 --- a/reactos/ntoskrnl/mm/mmfault.c +++ b/reactos/ntoskrnl/mm/mmfault.c @@ -150,7 +150,7 @@ MmNotPresentFault(KPROCESSOR_MODE Mode, MEMORY_AREA* MemoryArea; NTSTATUS Status; BOOLEAN Locked = FromMdl; - PFN_TYPE Pfn; + extern PMMPTE MmSharedUserDataPte; DPRINT("MmNotPresentFault(Mode %d, Address %x)\n", Mode, Address); @@ -228,14 +228,8 @@ MmNotPresentFault(KPROCESSOR_MODE Mode, break; case MEMORY_AREA_SHARED_DATA: - Pfn = MmGetPhysicalAddress((PVOID)PCR).LowPart >> PAGE_SHIFT; - Pfn++; - Status = - MmCreateVirtualMapping(PsGetCurrentProcess(), - (PVOID)PAGE_ROUND_DOWN(Address), - PAGE_READONLY, - &Pfn, - 1); + *MiAddressToPte(USER_SHARED_DATA) = *MmSharedUserDataPte; + Status = STATUS_SUCCESS; break; default: diff --git a/reactos/ntoskrnl/mm/mminit.c b/reactos/ntoskrnl/mm/mminit.c index b6702b18406..5d332a2864a 100644 --- a/reactos/ntoskrnl/mm/mminit.c +++ b/reactos/ntoskrnl/mm/mminit.c @@ -48,6 +48,7 @@ MemType[] = PBOOLEAN Mm64BitPhysicalAddress = FALSE; ULONG MmReadClusterSize; MM_STATS MmStats; +PMMPTE MmSharedUserDataPte; PMMSUPPORT MmKernelAddressSpace; extern KMUTANT MmSystemLoadLock; extern ULONG MmBootImageSize; @@ -181,6 +182,11 @@ NTAPI MmInitSystem(IN ULONG Phase, IN PLOADER_PARAMETER_BLOCK LoaderBlock) { + extern MMPTE HyperTemplatePte; + PMMPTE PointerPte; + MMPTE TempPte = HyperTemplatePte; + PFN_NUMBER PageFrameNumber; + if (Phase == 0) { /* Initialize Mm bootstrap */ @@ -210,6 +216,31 @@ MmInitSystem(IN ULONG Phase, MmInitSectionImplementation(); MmInitPagingFile(); + // + // Create a PTE to double-map the shared data section. We allocate it + // from paged pool so that we can't fault when trying to touch the PTE + // itself (to map it), since paged pool addresses will already be mapped + // by the fault handler. + // + MmSharedUserDataPte = ExAllocatePoolWithTag(PagedPool, + sizeof(MMPTE), + ' mM'); + if (!MmSharedUserDataPte) return FALSE; + + // + // Now get the PTE for shared data, and read the PFN that holds it + // + PointerPte = MiAddressToPte(KI_USER_SHARED_DATA); + ASSERT(PointerPte->u.Hard.Valid == 1); + PageFrameNumber = PFN_FROM_PTE(PointerPte); + + // + // Now write a copy of it + // + TempPte.u.Hard.Owner = 1; + TempPte.u.Hard.PageFrameNumber = PageFrameNumber; + *MmSharedUserDataPte = TempPte; + /* * Unmap low memory */