https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6a2eeaa5ae4948f9a3acc…
commit 6a2eeaa5ae4948f9a3acc019e5c13c9d92e2960a
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Thu Dec 26 20:30:54 2019 +0100
Commit: Jérôme Gardou <zefklop(a)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());