https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6a2eeaa5ae4948f9a3acc019e5c13c9d92e2960a

commit 6a2eeaa5ae4948f9a3acc019e5c13c9d92e2960a
Author:     Timo Kreuzer <[email protected]>
AuthorDate: Thu Dec 26 20:30:54 2019 +0100
Commit:     Jérôme Gardou <[email protected]>
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());

Reply via email to