[NTOS]: When expanding paged pool, use MiRemoveAnyPage, not MmAllocPage.
[reactos.git] / reactos / ntoskrnl / mm / ARM3 / pagfault.c
index dbed300..8fd0d15 100644 (file)
@@ -27,6 +27,10 @@ MiCheckPdeForPagedPool(IN PVOID Address)
     PMMPDE PointerPde;
     NTSTATUS Status = STATUS_SUCCESS;
     
+    /* No session support in ReactOS yet */
+    ASSERT(MI_IS_SESSION_ADDRESS(Address) == FALSE);
+    ASSERT(MI_IS_SESSION_PTE(Address) == FALSE);
+    
     //
     // Check if this is a fault while trying to access the page table itself
     //
@@ -60,6 +64,9 @@ MiCheckPdeForPagedPool(IN PVOID Address)
     //
     if (PointerPde->u.Hard.Valid == 0)
     {
+        /* This seems to be making the assumption that one PDE is one page long */
+        C_ASSERT(PAGE_SIZE == (PD_COUNT * (sizeof(MMPTE) * PDE_COUNT)));
+        
         //
         // Copy it from our double-mapped system page directory
         //
@@ -84,21 +91,26 @@ MiResolveDemandZeroFault(IN PVOID Address,
 {
     PFN_NUMBER PageFrameNumber;
     MMPTE TempPte;
-    DPRINT("ARM3 Demand Zero Page Fault Handler for address: %p in process: %p\n",
+    DPRINT1("ARM3 Demand Zero Page Fault Handler for address: %p in process: %p\n",
             Address,
             Process);
     
+    /* Must currently only be called by paging path, for system addresses only */
+    ASSERT(OldIrql == MM_NOIRQL);
+    ASSERT(Process == NULL);
+        
     //
     // Lock the PFN database
     //
     OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
     ASSERT(PointerPte->u.Hard.Valid == 0);
     
-    //
-    // Get a page
-    //
-    PageFrameNumber = MmAllocPage(MC_PPOOL);
-    DPRINT("New pool page: %lx\n", PageFrameNumber);
+    /* Get a page */
+    PageFrameNumber = MiRemoveAnyPage(0);
+    DPRINT1("New pool page: %lx\n", PageFrameNumber);
+    
+    /* Initialize it */
+    MiInitializePfn(PageFrameNumber, PointerPte, TRUE);
     
     //
     // Release PFN lock
@@ -110,18 +122,20 @@ MiResolveDemandZeroFault(IN PVOID Address,
     //
     InterlockedIncrement(&KeGetCurrentPrcb()->MmDemandZeroCount);
     
-    //
-    // Build the PTE
-    //
-    TempPte = ValidKernelPte;
-    TempPte.u.Hard.PageFrameNumber = PageFrameNumber;
+    /* Shouldn't see faults for user PTEs yet */
+    ASSERT(PointerPte > MiHighestUserPte);
+    
+    /* Build the PTE */
+    MI_MAKE_HARDWARE_PTE(&TempPte, PointerPte, PointerPte->u.Soft.Protection, PageFrameNumber);
+    ASSERT(TempPte.u.Hard.Valid == 1);
+    ASSERT(PointerPte->u.Hard.Valid == 0);
     *PointerPte = TempPte;
     ASSERT(PointerPte->u.Hard.Valid == 1);
     
     //
     // It's all good now
     //
-    DPRINT("Paged pool page has now been paged in\n");
+    DPRINT1("Paged pool page has now been paged in\n");
     return STATUS_PAGE_FAULT_DEMAND_ZERO;
 }
 
@@ -155,6 +169,9 @@ MiDispatchFault(IN BOOLEAN StoreInstruction,
     //
     TempPte = *PointerPte;
     
+    /* No prototype */
+    ASSERT(PrototypePte == NULL);
+    
     //
     // The PTE must be invalid, but not totally blank
     //
@@ -175,7 +192,8 @@ MiDispatchFault(IN BOOLEAN StoreInstruction,
     Status = MiResolveDemandZeroFault(Address,
                                       PointerPte,
                                       Process,
-                                      -1);
+                                      MM_NOIRQL);
+    ASSERT(KeAreAllApcsDisabled () == TRUE);
     if (NT_SUCCESS(Status))
     {
         //
@@ -304,7 +322,7 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
             //
             // This might happen...not sure yet
             //
-            DPRINT1("FAULT ON PAGE TABLES!\n");
+            DPRINT1("FAULT ON PAGE TABLES: %p %lx %lx!\n", Address, *PointerPte, *PointerPde);
             
             //
             // Map in the page table