https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6a2eeaa5ae4948f9a3acc0...
commit 6a2eeaa5ae4948f9a3acc019e5c13c9d92e2960a Author: Timo Kreuzer timo.kreuzer@reactos.org AuthorDate: Thu Dec 26 20:30:54 2019 +0100 Commit: Jérôme Gardou zefklop@users.noreply.github.com CommitDate: Wed Jun 9 11:27:18 2021 +0200
[NTOS] Implement MiIsPageTablePresent as a replacement for the abused MiQueryPageTableReferences --- ntoskrnl/mm/ARM3/miarm.h | 46 +-------------------------- ntoskrnl/mm/i386/page.c | 83 ++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 77 insertions(+), 52 deletions(-)
diff --git a/ntoskrnl/mm/ARM3/miarm.h b/ntoskrnl/mm/ARM3/miarm.h index 8c165759277..2145b4c319e 100644 --- a/ntoskrnl/mm/ARM3/miarm.h +++ b/ntoskrnl/mm/ARM3/miarm.h @@ -2549,57 +2549,13 @@ USHORT MiQueryPageTableReferences(IN PVOID Address) { PMMPDE PointerPde; - PMMPPE PointerPpe; -#if _MI_PAGING_LEVELS == 4 - PMMPXE PointerPxe; -#endif PMMPFN Pfn;
/* Make sure we're locked */ ASSERT((PsGetCurrentThread()->OwnsProcessWorkingSetExclusive) || (PsGetCurrentThread()->OwnsProcessWorkingSetShared));
- /* Check if PXE or PPE have references first. */ -#if _MI_PAGING_LEVELS == 4 - PointerPxe = MiAddressToPxe(Address); - if ((PointerPxe->u.Hard.Valid == 1) || (PointerPxe->u.Soft.Transition == 1)) - { - Pfn = MiGetPfnEntry(PFN_FROM_PXE(PointerPxe)); - if (Pfn->OriginalPte.u.Soft.UsedPageTableEntries == 0) - return 0; - } - else if (PointerPxe->u.Soft.UsedPageTableEntries == 0) - { - return 0; - } - - if (PointerPxe->u.Hard.Valid == 0) - { - MiMakeSystemAddressValid(MiPteToAddress(PointerPxe), PsGetCurrentProcess()); - } -#endif - - PointerPpe = MiAddressToPpe(Address); - if ((PointerPpe->u.Hard.Valid == 1) || (PointerPpe->u.Soft.Transition == 1)) - { - Pfn = MiGetPfnEntry(PFN_FROM_PPE(PointerPpe)); - if (Pfn->OriginalPte.u.Soft.UsedPageTableEntries == 0) - return 0; - } - else if (PointerPpe->u.Soft.UsedPageTableEntries == 0) - { - return 0; - } - - if (PointerPpe->u.Hard.Valid == 0) - { - MiMakeSystemAddressValid(MiPteToAddress(PointerPpe), PsGetCurrentProcess()); - } - PointerPde = MiAddressToPde(Address); - if ((PointerPde->u.Hard.Valid == 0) && (PointerPde->u.Soft.Transition == 0)) - { - return PointerPde->u.Soft.UsedPageTableEntries; - } + ASSERT(PointerPde->u.Hard.Valid);
/* This lies on the PFN */ Pfn = MiGetPfnEntry(PFN_FROM_PDE(PointerPde)); diff --git a/ntoskrnl/mm/i386/page.c b/ntoskrnl/mm/i386/page.c index 7e7db5bd431..2c402c51478 100644 --- a/ntoskrnl/mm/i386/page.c +++ b/ntoskrnl/mm/i386/page.c @@ -114,6 +114,75 @@ NTAPI MiFillSystemPageDirectory(IN PVOID Base, IN SIZE_T NumberOfBytes);
+static +BOOLEAN +MiIsPageTablePresent(PVOID Address) +{ +#if _MI_PAGING_LEVELS == 2 + return MiQueryPageTableReferences(Address) != 0; +#else + PMMPDE PointerPde; + PMMPPE PointerPpe; +#if _MI_PAGING_LEVELS == 4 + PMMPXE PointerPxe; +#endif + PMMPFN Pfn; + + /* Make sure we're locked */ + ASSERT((PsGetCurrentThread()->OwnsProcessWorkingSetExclusive) || (PsGetCurrentThread()->OwnsProcessWorkingSetShared)); + + /* Must not hold the PFN lock! */ + ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL); + + /* Check if PXE or PPE have references first. */ +#if _MI_PAGING_LEVELS == 4 + PointerPxe = MiAddressToPxe(Address); + if ((PointerPxe->u.Hard.Valid == 1) || (PointerPxe->u.Soft.Transition == 1)) + { + Pfn = MiGetPfnEntry(PFN_FROM_PXE(PointerPxe)); + if (Pfn->OriginalPte.u.Soft.UsedPageTableEntries == 0) + return FALSE; + } + else if (PointerPxe->u.Soft.UsedPageTableEntries == 0) + { + return FALSE; + } + + if (PointerPxe->u.Hard.Valid == 0) + { + MiMakeSystemAddressValid(MiPteToAddress(PointerPxe), PsGetCurrentProcess()); + } +#endif + + PointerPpe = MiAddressToPpe(Address); + if ((PointerPpe->u.Hard.Valid == 1) || (PointerPpe->u.Soft.Transition == 1)) + { + Pfn = MiGetPfnEntry(PFN_FROM_PPE(PointerPpe)); + if (Pfn->OriginalPte.u.Soft.UsedPageTableEntries == 0) + return FALSE; + } + else if (PointerPpe->u.Soft.UsedPageTableEntries == 0) + { + return FALSE; + } + + if (PointerPpe->u.Hard.Valid == 0) + { + MiMakeSystemAddressValid(MiPteToAddress(PointerPpe), PsGetCurrentProcess()); + } + + PointerPde = MiAddressToPde(Address); + if ((PointerPde->u.Hard.Valid == 0) && (PointerPde->u.Soft.Transition == 0)) + { + return PointerPde->u.Soft.UsedPageTableEntries != 0; + } + + /* This lies on the PFN */ + Pfn = MiGetPfnEntry(PFN_FROM_PDE(PointerPde)); + return Pfn->OriginalPte.u.Soft.UsedPageTableEntries != 0; +#endif +} + PFN_NUMBER NTAPI MmGetPfnForProcess(PEPROCESS Process, @@ -132,7 +201,7 @@ MmGetPfnForProcess(PEPROCESS Process, /* Lock for reading */ MiLockProcessWorkingSetShared(Process, PsGetCurrentThread());
- if (MiQueryPageTableReferences(Address) == 0) + if (!MiIsPageTablePresent(Address)) { MiUnlockProcessWorkingSetShared(Process, PsGetCurrentThread()); return 0; @@ -201,7 +270,7 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, MiLockProcessWorkingSetUnsafe(Process, PsGetCurrentThread());
/* No PDE --> No page */ - if (MiQueryPageTableReferences(Address) == 0) + if (!MiIsPageTablePresent(Address)) { MiUnlockProcessWorkingSetUnsafe(Process, PsGetCurrentThread()); if (WasDirty) @@ -332,7 +401,7 @@ MmIsPagePresent(PEPROCESS Process, PVOID Address)
MiLockProcessWorkingSetShared(Process, PsGetCurrentThread());
- if (MiQueryPageTableReferences(Address) == 0) + if (!MiIsPageTablePresent(Address)) { /* It can't be present if there is no PDE */ MiUnlockProcessWorkingSetShared(Process, PsGetCurrentThread()); @@ -375,7 +444,7 @@ MmIsDisabledPage(PEPROCESS Process, PVOID Address)
MiLockProcessWorkingSetShared(Process, PsGetCurrentThread());
- if (MiQueryPageTableReferences(Address) == 0) + if (!MiIsPageTablePresent(Address)) { /* It can't be disabled if there is no PDE */ MiUnlockProcessWorkingSetShared(Process, PsGetCurrentThread()); @@ -415,7 +484,7 @@ MmIsPageSwapEntry(PEPROCESS Process, PVOID Address)
MiLockProcessWorkingSetShared(Process, PsGetCurrentThread());
- if (MiQueryPageTableReferences(Address) == 0) + if (!MiIsPageTablePresent(Address)) { /* There can't be a swap entry if there is no PDE */ MiUnlockProcessWorkingSetShared(Process, PsGetCurrentThread()); @@ -451,7 +520,7 @@ MmGetPageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY* SwapEntry)
MiLockProcessWorkingSetShared(Process, PsGetCurrentThread());
- if (MiQueryPageTableReferences(Address) == 0) + if (!MiIsPageTablePresent(Address)) { /* There can't be a swap entry if there is no PDE */ MiUnlockProcessWorkingSetShared(Process, PsGetCurrentThread()); @@ -638,7 +707,7 @@ MmGetPageProtect(PEPROCESS Process, PVOID Address)
MiLockProcessWorkingSetShared(Process, PsGetCurrentThread());
- if (MiQueryPageTableReferences(Address) == 0) + if (!MiIsPageTablePresent(Address)) { /* It can't be present if there is no PDE */ MiUnlockProcessWorkingSetShared(Process, PsGetCurrentThread());