https://git.reactos.org/?p=reactos.git;a=commitdiff;h=370982aa1d75240282b9778b4916342b63984cac

commit 370982aa1d75240282b9778b4916342b63984cac
Author:     Jérôme Gardou <[email protected]>
AuthorDate: Wed Apr 7 08:49:26 2021 +0200
Commit:     Jérôme Gardou <[email protected]>
CommitDate: Thu Apr 8 15:40:37 2021 +0200

    [NTOS:MM] Make i386/page.c usable for all x86 variants
    
    This includes PAE & amd64
---
 ntoskrnl/mm/i386/page.c | 197 ++++++++++++++++++++++--------------------------
 1 file changed, 92 insertions(+), 105 deletions(-)

diff --git a/ntoskrnl/mm/i386/page.c b/ntoskrnl/mm/i386/page.c
index 8b3ed370e94..3e5f5797218 100644
--- a/ntoskrnl/mm/i386/page.c
+++ b/ntoskrnl/mm/i386/page.c
@@ -15,35 +15,13 @@
 
 #include <mm/ARM3/miarm.h>
 
-/* GLOBALS *****************************************************************/
-
-#define PA_BIT_PRESENT   (0)
-#define PA_BIT_READWRITE (1)
-#define PA_BIT_USER      (2)
-#define PA_BIT_WT        (3)
-#define PA_BIT_CD        (4)
-#define PA_BIT_ACCESSED  (5)
-#define PA_BIT_DIRTY     (6)
-#define PA_BIT_GLOBAL    (8)
-
-#define PA_PRESENT   (1 << PA_BIT_PRESENT)
-#define PA_READWRITE (1 << PA_BIT_READWRITE)
-#define PA_USER      (1 << PA_BIT_USER)
-#define PA_DIRTY     (1 << PA_BIT_DIRTY)
-#define PA_WT        (1 << PA_BIT_WT)
-#define PA_CD        (1 << PA_BIT_CD)
-#define PA_ACCESSED  (1 << PA_BIT_ACCESSED)
-#define PA_GLOBAL    (1 << PA_BIT_GLOBAL)
-
-#define IS_HYPERSPACE(v)    (((ULONG)(v) >= HYPER_SPACE && (ULONG)(v) <= 
HYPER_SPACE_END))
-
-#define PTE_TO_PFN(X)  ((X) >> PAGE_SHIFT)
-#define PFN_TO_PTE(X)  ((X) << PAGE_SHIFT)
-
-#define PAGE_MASK(x)           ((x)&(~0xfff))
+#ifndef _MI_PAGING_LEVELS
+#error "Dude, fix your stuff before using this file"
+#endif
 
+/* GLOBALS *****************************************************************/
 const
-ULONG
+ULONG_PTR
 MmProtectToPteMask[32] =
 {
     //
@@ -179,7 +157,7 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address,
  */
 {
     PMMPTE PointerPte;
-    ULONG Pte;
+    MMPTE OldPte;
 
     DPRINT("MmDeleteVirtualMapping(%p, %p, %p, %p)\n", Process, Address, 
WasDirty, Page);
 
@@ -196,8 +174,11 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address,
             DPRINT1("NULL process given for user-mode mapping at %p\n", 
Address);
             KeBugCheck(MEMORY_MANAGEMENT);
         }
-
+#if (_MI_PAGING_LEVELS == 2)
         if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
+#else
+        if (!MiIsPdeForAddressValid(Address))
+#endif
         {
             /* There can't be a page if there is no PDE */
             if (WasDirty)
@@ -234,9 +215,9 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address,
     }
 
     PointerPte = MiAddressToPte(Address);
-    Pte = InterlockedExchangePte(PointerPte, 0);
+    OldPte.u.Long = InterlockedExchangePte(PointerPte, 0);
 
-    if (Pte == 0)
+    if (OldPte.u.Long == 0)
     {
         /* There was nothing here */
         if (Address < MmSystemRangeStart)
@@ -249,9 +230,9 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address,
     }
 
     /* It must have been present, or not a swap entry */
-    ASSERT(FlagOn(Pte, PA_PRESENT) || !FlagOn(Pte, 0x800));
+    ASSERT(OldPte.u.Hard.Valid || !FlagOn(OldPte.u.Long, 0x800));
 
-    if (FlagOn(Pte, PA_PRESENT))
+    if (OldPte.u.Hard.Valid)
         KeInvalidateTlbEntry(Address);
 
     if (Address < MmSystemRangeStart)
@@ -269,9 +250,9 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address,
     }
 
     if (WasDirty)
-        *WasDirty = FlagOn(Pte, PA_DIRTY);
+        *WasDirty = !!OldPte.u.Hard.Dirty;
     if (Page)
-        *Page = PTE_TO_PFN(Pte);
+        *Page = OldPte.u.Hard.PageFrameNumber;
 }
 
 
@@ -283,7 +264,7 @@ MmDeletePageFileMapping(
     SWAPENTRY* SwapEntry)
 {
     PMMPTE PointerPte;
-    ULONG Pte;
+    MMPTE OldPte;
 
     /* This should not be called for kernel space anymore */
     ASSERT(Process != NULL);
@@ -304,10 +285,11 @@ MmDeletePageFileMapping(
     MiMakePdeExistAndMakeValid(MiAddressToPde(Address), Process, MM_NOIRQL);
 
     PointerPte = MiAddressToPte(Address);
-    Pte = InterlockedExchangePte(PointerPte, 0);
-    if (!FlagOn(Pte, 0x800) || FlagOn(Pte, PA_PRESENT))
+    OldPte.u.Long = InterlockedExchangePte(PointerPte, 0);
+    /* This must be a swap entry ! */
+    if (!FlagOn(OldPte.u.Long, 0x800) || OldPte.u.Hard.Valid)
     {
-        KeBugCheckEx(MEMORY_MANAGEMENT, Pte, (ULONG_PTR)Process, 
(ULONG_PTR)Address, 0);
+        KeBugCheckEx(MEMORY_MANAGEMENT, OldPte.u.Long, (ULONG_PTR)Process, 
(ULONG_PTR)Address, 0);
     }
 
     /* This used to be a non-zero PTE, now we can let the PDE go. */
@@ -322,22 +304,7 @@ MmDeletePageFileMapping(
 
     MiUnlockProcessWorkingSetUnsafe(Process, PsGetCurrentThread());
 
-    *SwapEntry = Pte >> 1;
-}
-
-BOOLEAN
-Mmi386MakeKernelPageTableGlobal(PVOID Address)
-{
-    PMMPDE PointerPde = MiAddressToPde(Address);
-    PMMPTE PointerPte = MiAddressToPte(Address);
-
-    if (PointerPde->u.Hard.Valid == 0)
-    {
-        if(!MiSynchronizeSystemPde(PointerPde))
-            return FALSE;
-        return PointerPte->u.Hard.Valid != 0;
-    }
-    return FALSE;
+    *SwapEntry = OldPte.u.Long >> 1;
 }
 
 BOOLEAN
@@ -349,7 +316,11 @@ MmIsPagePresent(PEPROCESS Process, PVOID Address)
     if (Address >= MmSystemRangeStart)
     {
         ASSERT(Process == NULL);
+#if _MI_PAGING_LEVELS == 2
         if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
+#else
+        if (!MiIsPdeForAddressValid(Address))
+#endif
         {
             /* It can't be present if there is no PDE */
             return FALSE;
@@ -384,18 +355,20 @@ NTAPI
 MmIsDisabledPage(PEPROCESS Process, PVOID Address)
 {
     BOOLEAN Ret;
-    ULONG Pte;
+    PMMPTE PointerPte;
 
     if (Address >= MmSystemRangeStart)
     {
         ASSERT(Process == NULL);
+#if _MI_PAGING_LEVELS == 2
         if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
+#else
+        if (!MiIsPdeForAddressValid(Address))
+#endif
         {
             /* It's not disabled if it's not present */
             return FALSE;
         }
-
-        Pte = MiAddressToPte(Address)->u.Long;
     }
     else
     {
@@ -412,11 +385,12 @@ MmIsDisabledPage(PEPROCESS Process, PVOID Address)
         }
 
         MiMakePdeExistAndMakeValid(MiAddressToPde(Address), Process, 
MM_NOIRQL);
-
-        Pte = MiAddressToPte(Address)->u.Long;
     }
 
-    Ret = !FlagOn(Pte, PA_PRESENT) && !FlagOn(Pte, 0x800) && (PAGE_MASK(Pte) 
!= 0);
+    PointerPte = MiAddressToPte(Address);
+    Ret = !PointerPte->u.Hard.Valid
+        && !FlagOn(PointerPte->u.Long, 0x800)
+        && (PointerPte->u.Hard.PageFrameNumber != 0);
 
     if (Address < MmSystemRangeStart)
         MiUnlockProcessWorkingSetShared(Process, PsGetCurrentThread());
@@ -429,7 +403,7 @@ NTAPI
 MmIsPageSwapEntry(PEPROCESS Process, PVOID Address)
 {
     BOOLEAN Ret;
-    ULONG Pte;
+    PMMPTE PointerPte;
 
     /* We never set swap entries for kernel addresses */
     if (Address >= MmSystemRangeStart)
@@ -452,8 +426,8 @@ MmIsPageSwapEntry(PEPROCESS Process, PVOID Address)
 
     MiMakePdeExistAndMakeValid(MiAddressToPde(Address), Process, MM_NOIRQL);
 
-    Pte = MiAddressToPte(Address)->u.Long;
-    Ret = !FlagOn(Pte, PA_PRESENT) && FlagOn(Pte, 0x800);
+    PointerPte = MiAddressToPte(Address);
+    Ret = !PointerPte->u.Hard.Valid && FlagOn(PointerPte->u.Long, 0x800);
 
     MiUnlockProcessWorkingSetShared(Process, PsGetCurrentThread());
 
@@ -464,7 +438,7 @@ VOID
 NTAPI
 MmGetPageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY* SwapEntry)
 {
-    ULONG Pte;
+    PMMPTE PointerPte;
 
     /* We never set swap entries for kernel addresses */
     if (Address >= MmSystemRangeStart)
@@ -489,9 +463,9 @@ MmGetPageFileMapping(PEPROCESS Process, PVOID Address, 
SWAPENTRY* SwapEntry)
 
     MiMakePdeExistAndMakeValid(MiAddressToPde(Address), Process, MM_NOIRQL);
 
-    Pte = MiAddressToPte(Address)->u.Long;
-    if (!FlagOn(Pte, PA_PRESENT) && FlagOn(Pte, 0x800))
-        *SwapEntry = Pte >> 1;
+    PointerPte = MiAddressToPte(Address);
+    if (!PointerPte->u.Hard.Valid && FlagOn(PointerPte->u.Long, 0x800))
+        *SwapEntry = PointerPte->u.Long >> 1;
     else
         *SwapEntry = 0;
 
@@ -505,7 +479,7 @@ MmCreatePageFileMapping(PEPROCESS Process,
                         SWAPENTRY SwapEntry)
 {
     PMMPTE PointerPte;
-    ULONG Pte;
+    ULONG_PTR Pte;
 
     /* This should not be called for kernel space anymore */
     ASSERT(Process != NULL);
@@ -571,8 +545,10 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
             DPRINT1("NULL process given for user-mode mapping at %p\n", 
Address);
             KeBugCheck(MEMORY_MANAGEMENT);
         }
+#if _MI_PAGING_LEVELS == 2
         if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
             MiFillSystemPageDirectory(Address, PAGE_SIZE);
+#endif
     }
     else
     {
@@ -631,7 +607,7 @@ MmCreateVirtualMapping(PEPROCESS Process,
     ASSERT((ULONG_PTR)Address % PAGE_SIZE == 0);
     if (!MmIsPageInUse(Page))
     {
-        DPRINT1("Page at address %x not in use\n", PFN_TO_PTE(Page));
+        DPRINT1("Page %lx is not in use\n", Page);
         KeBugCheck(MEMORY_MANAGEMENT);
     }
 
@@ -642,15 +618,21 @@ ULONG
 NTAPI
 MmGetPageProtect(PEPROCESS Process, PVOID Address)
 {
-    ULONG_PTR Pte;
+    PMMPTE PointerPte;
     ULONG Protect;
 
     if (Address >= MmSystemRangeStart)
     {
         ASSERT(Process == NULL);
 
+#if _MI_PAGING_LEVELS == 2
         if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
+#else
+        if (!MiIsPdeForAddressValid(Address))
+#endif
+        {
             return PAGE_NOACCESS;
+        }
     }
     else
     {
@@ -671,34 +653,29 @@ MmGetPageProtect(PEPROCESS Process, PVOID Address)
         MiMakePdeExistAndMakeValid(MiAddressToPde(Address), Process, 
MM_NOIRQL);
     }
 
-    Pte = MiAddressToPte(Address)->u.Long;
+    PointerPte = MiAddressToPte(Address);
 
-    if (!(Pte & PA_PRESENT))
+    if (!PointerPte->u.Flush.Valid)
     {
         Protect = PAGE_NOACCESS;
     }
     else
     {
-        if (Pte & PA_READWRITE)
-        {
+        if (PointerPte->u.Flush.CopyOnWrite)
+            Protect = PAGE_WRITECOPY;
+        else if (PointerPte->u.Flush.Write)
             Protect = PAGE_READWRITE;
-        }
         else
-        {
-            Protect = PAGE_EXECUTE_READ;
-        }
-        if (Pte & PA_CD)
-        {
+            Protect = PAGE_READONLY;
+#if _MI_PAGING_LEVELS >= 3
+        /* PAE & AMD64 long mode support NoExecute bit */
+        if (!PointerPte->u.Flush.NoExecute)
+            Protect <<= 4;
+#endif
+        if (PointerPte->u.Flush.CacheDisable)
             Protect |= PAGE_NOCACHE;
-        }
-        if (Pte & PA_WT)
-        {
+        if (PointerPte->u.Flush.WriteThrough)
             Protect |= PAGE_WRITETHROUGH;
-        }
-        if (!(Pte & PA_USER))
-        {
-            Protect |= PAGE_SYSTEM;
-        }
     }
 
     if (Address < MmSystemRangeStart)
@@ -713,8 +690,7 @@ MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG 
flProtect)
 {
     ULONG ProtectionMask;
     PMMPTE PointerPte;
-    MMPTE TempPte;
-    ULONG_PTR Pte;
+    MMPTE TempPte, OldPte;
 
     DPRINT("MmSetPageProtect(Process %p  Address %p  flProtect %x)\n",
            Process, Address, flProtect);
@@ -739,16 +715,16 @@ MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG 
flProtect)
     TempPte.u.Hard.Accessed = PointerPte->u.Hard.Accessed;
     TempPte.u.Hard.Dirty = PointerPte->u.Hard.Dirty;
 
-    Pte = InterlockedExchangePte(PointerPte, TempPte.u.Long);
+    OldPte.u.Long = InterlockedExchangePte(PointerPte, TempPte.u.Long);
 
     // We should be able to bring a page back from PAGE_NOACCESS
-    if ((Pte & 0x800) || !(Pte >> PAGE_SHIFT))
+    if (!OldPte.u.Hard.Valid && (FlagOn(OldPte.u.Long, 0x800) || 
(OldPte.u.Hard.PageFrameNumber == 0)))
     {
-        DPRINT1("Invalid Pte %lx\n", Pte);
+        DPRINT1("Invalid Pte %lx\n", OldPte.u.Long);
         KeBugCheck(MEMORY_MANAGEMENT);
     }
 
-    if (Pte != TempPte.u.Long)
+    if (OldPte.u.Long != TempPte.u.Long)
         KeInvalidateTlbEntry(Address);
 
     MiUnlockProcessWorkingSetUnsafe(Process, PsGetCurrentThread());
@@ -759,7 +735,6 @@ NTAPI
 MmSetDirtyBit(PEPROCESS Process, PVOID Address, BOOLEAN Bit)
 {
     PMMPTE PointerPte;
-    ULONG Pte;
 
     DPRINT("MmSetDirtyBit(Process %p  Address %p  Bit %x)\n",
            Process, Address, Bit);
@@ -774,20 +749,15 @@ MmSetDirtyBit(PEPROCESS Process, PVOID Address, BOOLEAN 
Bit)
     MiMakePdeExistAndMakeValid(MiAddressToPde(Address), Process, MM_NOIRQL);
 
     PointerPte = MiAddressToPte(Address);
-    Pte = PointerPte->u.Long;
-    if (Bit)
-        Pte |= PA_DIRTY;
-    else
-        Pte &= ~PA_DIRTY;
-    Pte = InterlockedExchangePte(PointerPte, Pte);
-
     // We shouldnl't set dirty bit on non-mapped adresses
-    if ((Pte & 0x800) || !(Pte >> PAGE_SHIFT))
+    if (!PointerPte->u.Hard.Valid && (FlagOn(PointerPte->u.Long, 0x800) || 
(PointerPte->u.Hard.PageFrameNumber == 0)))
     {
-        DPRINT1("Invalid Pte %lx\n", Pte);
+        DPRINT1("Invalid Pte %lx\n", PointerPte->u.Long);
         KeBugCheck(MEMORY_MANAGEMENT);
     }
 
+    PointerPte->u.Hard.Dirty = !!Bit;
+
     if (!Bit)
         KeInvalidateTlbEntry(Address);
 
@@ -802,4 +772,21 @@ MmInitGlobalKernelPageDirectory(VOID)
     /* Nothing to do here */
 }
 
+#ifdef _M_IX86
+BOOLEAN
+Mmi386MakeKernelPageTableGlobal(PVOID Address)
+{
+    PMMPDE PointerPde = MiAddressToPde(Address);
+    PMMPTE PointerPte = MiAddressToPte(Address);
+
+    if (PointerPde->u.Hard.Valid == 0)
+    {
+        if (!MiSynchronizeSystemPde(PointerPde))
+            return FALSE;
+        return PointerPte->u.Hard.Valid != 0;
+    }
+    return FALSE;
+}
+#endif
+
 /* EOF */

Reply via email to