Author: tkreuzer
Date: Sun Feb  5 17:19:58 2012
New Revision: 55433

URL: http://svn.reactos.org/svn/reactos?rev=55433&view=rev
Log:
[NTOSKRNL]
Handle _MI_PAGING_LEVELS >= 3 in MiBuildPagedPool and MmArmAccessFault

Modified:
    trunk/reactos/ntoskrnl/mm/ARM3/mminit.c
    trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c

Modified: trunk/reactos/ntoskrnl/mm/ARM3/mminit.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/mminit.c?rev=55433&r1=55432&r2=55433&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/mminit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/mminit.c [iso-8859-1] Sun Feb  5 17:19:58 
2012
@@ -1605,7 +1605,10 @@
     KIRQL OldIrql;
     SIZE_T Size;
     ULONG BitMapSize;
-#if (_MI_PAGING_LEVELS == 2)
+#if (_MI_PAGING_LEVELS >= 3)
+    MMPPE TempPpe = ValidKernelPpe;
+    PMMPPE PointerPpe;
+#elif (_MI_PAGING_LEVELS == 2)
     MMPTE TempPte = ValidKernelPte;
 
     //
@@ -1682,17 +1685,32 @@
                               MmSizeOfPagedPoolInBytes) - 1);
 
     //
-    // So now get the PDE for paged pool and zero it out
-    //
-    PointerPde = MiAddressToPde(MmPagedPoolStart);
+    // Lock the PFN database
+    //
+    OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
 
 #if (_MI_PAGING_LEVELS >= 3)
-    /* On these systems, there's no double-mapping, so instead, the PPE and 
PXEs
+    /* On these systems, there's no double-mapping, so instead, the PPEs
      * are setup to span the entire paged pool area, so there's no need for the
      * system PD */
-     ASSERT(FALSE);
+    for (PointerPpe = MiAddressToPpe(MmPagedPoolStart);
+         PointerPpe <= MiAddressToPpe(MmPagedPoolEnd);
+         PointerPpe++)
+    {
+        /* Check if the PPE is already valid */
+        if (!PointerPpe->u.Hard.Valid)
+        {
+            /* It is not, so map a fresh zeroed page */
+            TempPpe.u.Hard.PageFrameNumber = MiRemoveZeroPage(0);
+            MI_WRITE_VALID_PPE(PointerPpe, TempPpe);
+        }
+    }
 #endif
 
+    //
+    // So now get the PDE for paged pool and zero it out
+    //
+    PointerPde = MiAddressToPde(MmPagedPoolStart);
     RtlZeroMemory(PointerPde,
                   (1 + MiAddressToPde(MmPagedPoolEnd) - PointerPde) * 
sizeof(MMPDE));
 
@@ -1702,11 +1720,6 @@
     PointerPte = MiAddressToPte(MmPagedPoolStart);
     MmPagedPoolInfo.FirstPteForPagedPool = PointerPte;
     MmPagedPoolInfo.LastPteForPagedPool = MiAddressToPte(MmPagedPoolEnd);
-
-    //
-    // Lock the PFN database
-    //
-    OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
 
     /* Allocate a page and map the first paged pool PDE */
     MI_SET_USAGE(MI_USAGE_PAGED_POOL);
@@ -1717,7 +1730,11 @@
 #if (_MI_PAGING_LEVELS >= 3)
     /* Use the PPE of MmPagedPoolStart that was setup above */
 //    Bla = PFN_FROM_PTE(PpeAddress(MmPagedPool...));
-    ASSERT(FALSE);
+
+    /* Initialize the PFN entry for it */
+    MiInitializePfnForOtherProcess(PageFrameIndex,
+                                   (PMMPTE)PointerPde,
+                                   
PFN_FROM_PTE(MiAddressToPpe(MmPagedPoolStart)));
 #else
     /* Do it this way */
 //    Bla = MmSystemPageDirectory[(PointerPde - (PMMPTE)PDE_BASE) / PDE_COUNT]

Modified: trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c?rev=55433&r1=55432&r2=55433&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] Sun Feb  5 17:19:58 
2012
@@ -637,8 +637,15 @@
                  IN PVOID TrapInformation)
 {
     KIRQL OldIrql = KeGetCurrentIrql(), LockIrql;
-    PMMPTE PointerPte, ProtoPte = NULL;
-    PMMPDE PointerPde;
+    PMMPTE ProtoPte = NULL;
+    PMMPTE PointerPte = MiAddressToPte(Address);
+    PMMPDE PointerPde = MiAddressToPde(Address);
+#if (_MI_PAGING_LEVELS >= 3)
+    PMMPDE PointerPpe = MiAddressToPpe(Address);
+#if (_MI_PAGING_LEVELS == 4)
+    PMMPDE PointerPxe = MiAddressToPxe(Address);
+#endif
+#endif
     MMPTE TempPte;
     PETHREAD CurrentThread;
     PEPROCESS CurrentProcess;
@@ -648,17 +655,8 @@
     PMMVAD Vad;
     PFN_NUMBER PageFrameIndex;
     ULONG Color;
+
     DPRINT("ARM3 FAULT AT: %p\n", Address);
-
-    //
-    // Get the PTE and PDE
-    //
-    PointerPte = MiAddressToPte(Address);
-    PointerPde = MiAddressToPde(Address);
-#if (_MI_PAGING_LEVELS >= 3)
-    /* We need the PPE and PXE addresses */
-    ASSERT(FALSE);
-#endif
 
     //
     // Check for dispatch-level snafu
@@ -675,7 +673,7 @@
     }
 
     //
-    // Check for kernel fault
+    // Check for kernel fault address
     //
     while (Address >= MmSystemRangeStart)
     {
@@ -685,8 +683,18 @@
         if (Mode == UserMode) return STATUS_ACCESS_VIOLATION;
 
 #if (_MI_PAGING_LEVELS >= 3)
-        /* Need to check PXE and PDE validity */
-        ASSERT(FALSE);
+        if (
+#if (_MI_PAGING_LEVELS == 4)
+            (PointerPxe->u.Hard.Valid == 0) ||
+#endif
+            (PointerPpe->u.Hard.Valid == 0))
+        {
+            KeBugCheckEx(PAGE_FAULT_IN_NONPAGED_AREA,
+                         (ULONG_PTR)Address,
+                         StoreInstruction,
+                         (ULONG_PTR)TrapInformation,
+                         2);
+        }
 #endif
 
         //
@@ -871,17 +879,20 @@
         return Status;
     }
 
-    /* This is a user fault */
+#if (_MI_PAGING_LEVELS == 4)
+    /* On these systems we have PXEs and PPEs ready for everything we need */
+    if (PointerPxe->u.Hard.Valid == 0) return STATUS_ACCESS_VIOLATION;
+#endif
+#if (_MI_PAGING_LEVELS >= 3)
+    if (PointerPpe->u.Hard.Valid == 0) return STATUS_ACCESS_VIOLATION;
+#endif
+
+    /* This is a user fault (<- And this is a lie!) */
     CurrentThread = PsGetCurrentThread();
     CurrentProcess = PsGetCurrentProcess();
 
     /* Lock the working set */
     MiLockProcessWorkingSet(CurrentProcess, CurrentThread);
-
-#if (_MI_PAGING_LEVELS >= 3)
-    /* Need to check/handle PPE and PXE validity too */
-    ASSERT(FALSE);
-#endif
 
     /* First things first, is the PDE valid? */
     ASSERT(PointerPde->u.Hard.LargePage == 0);
@@ -916,10 +927,6 @@
 #endif
         /* We should come back with APCs enabled, and with a valid PDE */
         ASSERT(KeAreAllApcsDisabled() == TRUE);
-#if (_MI_PAGING_LEVELS >= 3)
-        /* Need to check/handle PPE and PXE validity too */
-        ASSERT(FALSE);
-#endif
         ASSERT(PointerPde->u.Hard.Valid == 1);
     }
 


Reply via email to