From d059077864415af6247511ead93f23cc13f4fa72 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sat, 23 Nov 2013 22:34:20 +0000 Subject: [PATCH] [NTOSKRNL] - Use MI_IS_MAPPED_PTE instead of unportable bit fiddling - Use MiDecrementPageTableReferences instead of manually messing with MmWorkingSetList, which is not portable - Make MmGetPhysicalAddress portable svn path=/trunk/; revision=61086 --- reactos/ntoskrnl/include/internal/amd64/mm.h | 9 +++ reactos/ntoskrnl/mm/ARM3/miarm.h | 8 +++ reactos/ntoskrnl/mm/ARM3/virtual.c | 59 +++++++++++++++++--- reactos/ntoskrnl/mm/amd64/page.c | 21 ------- reactos/ntoskrnl/mm/i386/page.c | 26 --------- 5 files changed, 69 insertions(+), 54 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/amd64/mm.h b/reactos/ntoskrnl/include/internal/amd64/mm.h index 5986da62c62..0021a0569a2 100644 --- a/reactos/ntoskrnl/include/internal/amd64/mm.h +++ b/reactos/ntoskrnl/include/internal/amd64/mm.h @@ -290,6 +290,15 @@ MI_MAKE_PROTOTYPE_PTE(IN PMMPTE NewPte, ASSERT(MiProtoPteToPte(NewPte) == PointerPte); } +FORCEINLINE +BOOLEAN +MI_IS_MAPPED_PTE(PMMPTE PointerPte) +{ + /// FIXME + __debugbreak(); + return (PointerPte->u.Long & 0xFFFFFC01 != 0); +} + VOID FORCEINLINE MmInitGlobalKernelPageDirectory(VOID) diff --git a/reactos/ntoskrnl/mm/ARM3/miarm.h b/reactos/ntoskrnl/mm/ARM3/miarm.h index b1efe38dd4f..02e72870cda 100644 --- a/reactos/ntoskrnl/mm/ARM3/miarm.h +++ b/reactos/ntoskrnl/mm/ARM3/miarm.h @@ -950,6 +950,14 @@ MI_MAKE_SUBSECTION_PTE(IN PMMPTE NewPte, NewPte->u.Subsect.SubsectionAddressHigh = (Offset & 0xFFFFF80) >> 7; } +FORCEINLINE +BOOLEAN +MI_IS_MAPPED_PTE(PMMPTE PointerPte) +{ + /// \todo Make this reasonable code, this is UGLY! + return ((PointerPte->u.Long & 0xFFFFFC01) != 0); +} + #endif // diff --git a/reactos/ntoskrnl/mm/ARM3/virtual.c b/reactos/ntoskrnl/mm/ARM3/virtual.c index 2b29549c7f8..981fefbff1d 100644 --- a/reactos/ntoskrnl/mm/ARM3/virtual.c +++ b/reactos/ntoskrnl/mm/ARM3/virtual.c @@ -503,7 +503,6 @@ MiDeleteVirtualAddresses(IN ULONG_PTR Va, KIRQL OldIrql; BOOLEAN AddressGap = FALSE; PSUBSECTION Subsection; - PUSHORT UsedPageTableEntries; /* Get out if this is a fake VAD, RosMm will free the marea pages */ if ((Vad) && (Vad->u.VadFlags.Spare == 1)) return; @@ -560,7 +559,6 @@ MiDeleteVirtualAddresses(IN ULONG_PTR Va, /* Now we should have a valid PDE, mapped in, and still have some VA */ ASSERT(PointerPde->u.Hard.Valid == 1); ASSERT(Va <= EndingAddress); - UsedPageTableEntries = &MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Va)]; /* Check if this is a section VAD with gaps in it */ if ((AddressGap) && (LastPrototypePte)) @@ -590,11 +588,10 @@ MiDeleteVirtualAddresses(IN ULONG_PTR Va, TempPte = *PointerPte; if (TempPte.u.Long) { - *UsedPageTableEntries -= 1; - ASSERT((*UsedPageTableEntries) < PTE_COUNT); + MiDecrementPageTableReferences((PVOID)Va); /* Check if the PTE is actually mapped in */ - if (TempPte.u.Long & 0xFFFFFC01) + if (MI_IS_MAPPED_PTE(&TempPte)) { /* Are we dealing with section VAD? */ if ((LastPrototypePte) && (PrototypePte > LastPrototypePte)) @@ -652,7 +649,8 @@ MiDeleteVirtualAddresses(IN ULONG_PTR Va, /* The PDE should still be valid at this point */ ASSERT(PointerPde->u.Hard.Valid == 1); - if (*UsedPageTableEntries == 0) + /* Check remaining PTE count (go back 1 page due to above loop) */ + if (MiQueryPageTableReferences((PVOID)(Va - PAGE_SIZE)) == 0) { if (PointerPde->u.Long != 0) { @@ -4078,7 +4076,7 @@ NtAllocateVirtualMemory(IN HANDLE ProcessHandle, Status = STATUS_CONFLICTING_ADDRESSES; goto FailPath; } - + if ((AllocationType & MEM_RESET) == MEM_RESET) { /// @todo HACK: pretend success @@ -4253,6 +4251,7 @@ NtAllocateVirtualMemory(IN HANDLE ProcessHandle, // TempPte.u.Long = 0; TempPte.u.Soft.Protection = ProtectionMask; + NT_ASSERT(TempPte.u.Long != 0); // // Get the PTE, PDE and the last PTE for this address range @@ -4832,4 +4831,50 @@ FailPath: return Status; } + +PHYSICAL_ADDRESS +NTAPI +MmGetPhysicalAddress(PVOID Address) +{ + PHYSICAL_ADDRESS PhysicalAddress; + MMPDE TempPde; + MMPTE TempPte; + + /* Check if the PXE/PPE/PDE is valid */ + if ( +#if (_MI_PAGING_LEVELS == 4) + (MiAddressToPxe(Address)->u.Hard.Valid) && +#endif +#if (_MI_PAGING_LEVELS >= 3) + (MiAddressToPpe(Address)->u.Hard.Valid) && +#endif + (MiAddressToPde(Address)->u.Hard.Valid)) + { + /* Check for large pages */ + TempPde = *MiAddressToPde(Address); + if (TempPde.u.Hard.LargePage) + { + /* Physical address is base page + large page offset */ + PhysicalAddress.QuadPart = TempPde.u.Hard.PageFrameNumber << PAGE_SHIFT; + PhysicalAddress.QuadPart += ((ULONG_PTR)Address & (PAGE_SIZE * PTE_PER_PAGE - 1)); + return PhysicalAddress; + } + + /* Check if the PTE is valid */ + TempPte = *MiAddressToPte(Address); + if (TempPte.u.Hard.Valid) + { + /* Physical address is base page + page offset */ + PhysicalAddress.QuadPart = TempPte.u.Hard.PageFrameNumber << PAGE_SHIFT; + PhysicalAddress.QuadPart += ((ULONG_PTR)Address & (PAGE_SIZE - 1)); + return PhysicalAddress; + } + } + + DPRINT1("MM:MmGetPhysicalAddressFailed base address was %p", Address); + PhysicalAddress.QuadPart = 0; + return PhysicalAddress; +} + + /* EOF */ diff --git a/reactos/ntoskrnl/mm/amd64/page.c b/reactos/ntoskrnl/mm/amd64/page.c index ee73689bfd5..bea56a0195f 100644 --- a/reactos/ntoskrnl/mm/amd64/page.c +++ b/reactos/ntoskrnl/mm/amd64/page.c @@ -348,27 +348,6 @@ MmGetPfnForProcess(PEPROCESS Process, return Pte.u.Hard.Valid ? Pte.u.Hard.PageFrameNumber : 0; } -PHYSICAL_ADDRESS -NTAPI -MmGetPhysicalAddress(PVOID Address) -{ - PHYSICAL_ADDRESS p; - MMPTE Pte; - - Pte.u.Long = MiGetPteValueForProcess(NULL, Address); - if (Pte.u.Hard.Valid) - { - p.QuadPart = Pte.u.Hard.PageFrameNumber * PAGE_SIZE; - p.u.LowPart |= (ULONG_PTR)Address & (PAGE_SIZE - 1); - } - else - { - p.QuadPart = 0; - } - - return p; -} - BOOLEAN NTAPI MmIsPagePresent(PEPROCESS Process, PVOID Address) diff --git a/reactos/ntoskrnl/mm/i386/page.c b/reactos/ntoskrnl/mm/i386/page.c index 6d63d243e34..ea30ce9e608 100644 --- a/reactos/ntoskrnl/mm/i386/page.c +++ b/reactos/ntoskrnl/mm/i386/page.c @@ -1004,32 +1004,6 @@ MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect) MmUnmapPageTable(Pt); } -/* - * @implemented - */ -PHYSICAL_ADDRESS NTAPI -MmGetPhysicalAddress(PVOID vaddr) -/* - * FUNCTION: Returns the physical address corresponding to a virtual address - */ -{ - PHYSICAL_ADDRESS p; - ULONG Pte; - - DPRINT("MmGetPhysicalAddress(vaddr %p)\n", vaddr); - Pte = MmGetPageEntryForProcess(NULL, vaddr); - if (Pte != 0 && (Pte & PA_PRESENT)) - { - p.QuadPart = PAGE_MASK(Pte); - p.u.LowPart |= (ULONG_PTR)vaddr & (PAGE_SIZE - 1); - } - else - { - p.QuadPart = 0; - } - return p; -} - VOID INIT_FUNCTION NTAPI