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

commit a80ae8f2ea3e9500b4f6c6215fb52d0c20ccddea
Author:     Jérôme Gardou <[email protected]>
AuthorDate: Tue May 25 16:08:25 2021 +0200
Commit:     Jérôme Gardou <[email protected]>
CommitDate: Wed Jun 9 11:27:18 2021 +0200

    [NTOS:MM] Make MiCalculatePageCommitment 64-bits aware
---
 ntoskrnl/mm/ARM3/virtual.c | 208 ++++++++++++++++++++-------------------------
 1 file changed, 93 insertions(+), 115 deletions(-)

diff --git a/ntoskrnl/mm/ARM3/virtual.c b/ntoskrnl/mm/ARM3/virtual.c
index ace22a19887..c8a24e08231 100644
--- a/ntoskrnl/mm/ARM3/virtual.c
+++ b/ntoskrnl/mm/ARM3/virtual.c
@@ -46,157 +46,135 @@ MiCalculatePageCommitment(IN ULONG_PTR StartingAddress,
 {
     PMMPTE PointerPte, LastPte;
     PMMPDE PointerPde;
-    ULONG CommittedPages;
+    BOOLEAN OnPdeBoundary = TRUE;
+#if _MI_PAGING_LEVELS >= 3
+    PMMPPE PointerPpe;
+    BOOLEAN OnPpeBoundary = TRUE;
+#if _MI_PAGING_LEVELS == 4
+    PMMPXE PointerPxe;
+    BOOLEAN OnPxeBoundary = TRUE;
+#endif
+#endif
 
-    /* Compute starting and ending PTE and PDE addresses */
-    PointerPde = MiAddressToPde(StartingAddress);
+    /* Make sure this all makes sense */
+    ASSERT(PsGetCurrentThread()->OwnsProcessWorkingSetExclusive || 
PsGetCurrentThread()->OwnsProcessWorkingSetShared);
+    ASSERT(EndingAddress >= StartingAddress);
     PointerPte = MiAddressToPte(StartingAddress);
     LastPte = MiAddressToPte(EndingAddress);
 
-    /* Handle commited pages first */
-    if (Vad->u.VadFlags.MemCommit == 1)
-    {
-        /* This is a committed VAD, so Assume the whole range is committed */
-        CommittedPages = (ULONG)BYTES_TO_PAGES(EndingAddress - 
StartingAddress);
+    /*
+     * In case this is a committed VAD, assume the whole range is committed
+     * and count the individually decommitted pages.
+     * In case it is not, assume the range is not committed and count the 
individually committed pages.
+     */
+    ULONG_PTR CommittedPages = Vad->u.VadFlags.MemCommit ? 
BYTES_TO_PAGES(EndingAddress - StartingAddress) : 0;
 
-        /* Is the PDE demand-zero? */
-        PointerPde = MiPteToPde(PointerPte);
-        if (PointerPde->u.Long != 0)
-        {
-            /* It is not. Is it valid? */
-            if (PointerPde->u.Hard.Valid == 0)
-            {
-                /* Fault it in */
-                PointerPte = MiPteToAddress(PointerPde);
-                MiMakeSystemAddressValid(PointerPte, Process);
-            }
-        }
-        else
+    while (PointerPte <= LastPte)
+    {
+#if _MI_PAGING_LEVELS == 4
+        /* Check if PXE was ever paged in. */
+        if (OnPxeBoundary)
         {
-            /* It is, skip it and move to the next PDE, unless we're done */
-            PointerPde++;
-            PointerPte = MiPteToAddress(PointerPde);
-            if (PointerPte > LastPte) return CommittedPages;
-        }
+            PointerPxe = MiPteToPxe(PointerPte);
 
-        /* Now loop all the PTEs in the range */
-        while (PointerPte <= LastPte)
-        {
-            /* Have we crossed a PDE boundary? */
-            if (MiIsPteOnPdeBoundary(PointerPte))
-            {
-                /* Is this PDE demand zero? */
-                PointerPde = MiPteToPde(PointerPte);
-                if (PointerPde->u.Long != 0)
-                {
-                    /* It isn't -- is it valid? */
-                    if (PointerPde->u.Hard.Valid == 0)
-                    {
-                        /* Nope, fault it in */
-                        PointerPte = MiPteToAddress(PointerPde);
-                        MiMakeSystemAddressValid(PointerPte, Process);
-                    }
-                }
-                else
-                {
-                    /* It is, skip it and move to the next PDE */
-                    PointerPde++;
-                    PointerPte = MiPteToAddress(PointerPde);
-                    continue;
-                }
-            }
+            /* Check that this loop is sane */
+            ASSERT(OnPpeBoundary);
+            ASSERT(OnPdeBoundary);
 
-            /* Is this PTE demand zero? */
-            if (PointerPte->u.Long != 0)
+            if (PointerPxe->u.Long == 0)
             {
-                /* It isn't -- is it a decommited, invalid, or faulted PTE? */
-                if ((PointerPte->u.Soft.Protection == MM_DECOMMIT) &&
-                    (PointerPte->u.Hard.Valid == 0) &&
-                    ((PointerPte->u.Soft.Prototype == 0) ||
-                     (PointerPte->u.Soft.PageFileHigh == 
MI_PTE_LOOKUP_NEEDED)))
-                {
-                    /* It is, so remove it from the count of commited pages */
-                    CommittedPages--;
-                }
+                PointerPxe++;
+                PointerPte = MiPxeToPte(PointerPde);
+                continue;
             }
 
-            /* Move to the next PTE */
-            PointerPte++;
+            if (PointerPxe->u.Hard.Valid == 0)
+                MiMakeSystemAddressValid(MiPteToPpe(PointerPte), Process);
         }
+        ASSERT(PointerPxe->u.Hard.Valid == 1);
+#endif
 
-        /* Return how many committed pages there still are */
-        return CommittedPages;
-    }
+#if _MI_PAGING_LEVELS >= 3
+        /* Now PPE */
+        if (OnPpeBoundary)
+        {
+            PointerPpe = MiPteToPpe(PointerPte);
 
-    /* This is a non-commited VAD, so assume none of it is committed */
-    CommittedPages = 0;
+            /* Sanity again */
+            ASSERT(OnPdeBoundary);
 
-    /* Is the PDE demand-zero? */
-    PointerPde = MiPteToPde(PointerPte);
-    if (PointerPde->u.Long != 0)
-    {
-        /* It isn't -- is it invalid? */
-        if (PointerPde->u.Hard.Valid == 0)
-        {
-            /* It is, so page it in */
-            PointerPte = MiPteToAddress(PointerPde);
-            MiMakeSystemAddressValid(PointerPte, Process);
+            if (PointerPpe->u.Long == 0)
+            {
+                PointerPpe++;
+                PointerPte = MiPpeToPte(PointerPpe);
+#if _MI_PAGING_LEVELS == 4
+                OnPxeBoundary = MiIsPteOnPxeBoundary(PointerPte);
+#endif
+                continue;
+            }
+
+            if (PointerPpe->u.Hard.Valid == 0)
+                MiMakeSystemAddressValid(MiPteToPde(PointerPte), Process);
         }
-    }
-    else
-    {
-        /* It is, so skip it and move to the next PDE */
-        PointerPde++;
-        PointerPte = MiPteToAddress(PointerPde);
-        if (PointerPte > LastPte) return CommittedPages;
-    }
+        ASSERT(PointerPpe->u.Hard.Valid == 1);
+#endif
 
-    /* Loop all the PTEs in this PDE */
-    while (PointerPte <= LastPte)
-    {
-        /* Have we crossed a PDE boundary? */
-        if (MiIsPteOnPdeBoundary(PointerPte))
+        /* Last level is the PDE */
+        if (OnPdeBoundary)
         {
-            /* Is this new PDE demand-zero? */
             PointerPde = MiPteToPde(PointerPte);
-            if (PointerPde->u.Long != 0)
+            if (PointerPde->u.Long == 0)
             {
-                /* It isn't. Is it valid? */
-                if (PointerPde->u.Hard.Valid == 0)
-                {
-                    /* It isn't, so make it valid */
-                    PointerPte = MiPteToAddress(PointerPde);
-                    MiMakeSystemAddressValid(PointerPte, Process);
-                }
-            }
-            else
-            {
-                /* It is, so skip it and move to the next one */
                 PointerPde++;
-                PointerPte = MiPteToAddress(PointerPde);
+                PointerPte = MiPdeToPte(PointerPde);
+#if _MI_PAGING_LEVELS >= 3
+                OnPpeBoundary = MiIsPteOnPpeBoundary(PointerPte);
+#if _MI_PAGING_LEVELS == 4
+                OnPxeBoundary = MiIsPteOnPxeBoundary(PointerPte);
+#endif
+#endif
                 continue;
             }
+
+            if (PointerPde->u.Hard.Valid == 0)
+                MiMakeSystemAddressValid(PointerPte, Process);
         }
+        ASSERT(PointerPde->u.Hard.Valid == 1);
 
-        /* Is this PTE demand-zero? */
+        /* Is this PTE demand zero? */
         if (PointerPte->u.Long != 0)
         {
-            /* Nope. Is it a valid, non-decommited, non-paged out PTE? */
-            if ((PointerPte->u.Soft.Protection != MM_DECOMMIT) ||
-                (PointerPte->u.Hard.Valid == 1) ||
-                ((PointerPte->u.Soft.Prototype == 1) &&
-                 (PointerPte->u.Soft.PageFileHigh != MI_PTE_LOOKUP_NEEDED)))
+            /* It isn't -- is it a decommited, invalid, or faulted PTE? */
+            if ((PointerPte->u.Hard.Valid == 0) &&
+                (PointerPte->u.Soft.Protection == MM_DECOMMIT) &&
+                ((PointerPte->u.Soft.Prototype == 0) ||
+                    (PointerPte->u.Soft.PageFileHigh == MI_PTE_LOOKUP_NEEDED)))
             {
-                /* It is! So we'll treat this as a committed page */
+                /* It is, so remove it from the count of committed pages if we 
have to */
+                if (Vad->u.VadFlags.MemCommit)
+                    CommittedPages--;
+            }
+            else if (!Vad->u.VadFlags.MemCommit)
+            {
+                /* It is a valid, non-decommited, non-paged out PTE. Count it 
in. */
                 CommittedPages++;
             }
         }
 
         /* Move to the next PTE */
         PointerPte++;
+        /* Manage page tables */
+        OnPdeBoundary = MiIsPteOnPdeBoundary(PointerPte);
+#if _MI_PAGING_LEVELS >= 3
+        OnPpeBoundary = MiIsPteOnPpeBoundary(PointerPte);
+#if _MI_PAGING_LEVELS == 4
+        OnPxeBoundary = MiIsPteOnPxeBoundary(PointerPte);
+#endif
+#endif
     }
 
-    /* Return how many committed pages we found in this VAD */
+    /* Make sure we didn't mess this up */
+    ASSERT(CommittedPages <= BYTES_TO_PAGES(EndingAddress - StartingAddress));
     return CommittedPages;
 }
 

Reply via email to