* Sync up to trunk head (r64716).
[reactos.git] / ntoskrnl / mm / ARM3 / sysldr.c
index de12395..b77bc90 100644 (file)
@@ -99,6 +99,8 @@ MiLoadImageSection(IN OUT PVOID *SectionPtr,
     PMMPTE PointerPte, LastPte;
     PVOID DriverBase;
     MMPTE TempPte;
+    KIRQL OldIrql;
+    PFN_NUMBER PageFrameIndex;
     PAGED_CODE();
 
     /* Detect session load */
@@ -173,31 +175,46 @@ MiLoadImageSection(IN OUT PVOID *SectionPtr,
     *ImageBase = DriverBase;
     DPRINT1("Loading: %wZ at %p with %lx pages\n", FileName, DriverBase, PteCount);
 
-    /* Loop the new driver PTEs */
-    TempPte = ValidKernelPte;
-    while (PointerPte < LastPte)
-    {
-        /* Allocate a page */
-        MI_SET_USAGE(MI_USAGE_DRIVER_PAGE);
+    /* Lock the PFN database */
+    OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+
+    /* Some debug stuff */
+    MI_SET_USAGE(MI_USAGE_DRIVER_PAGE);
 #if MI_TRACE_PFNS
+    if (FileName->Buffer)
+    {
         PWCHAR pos = NULL;
         ULONG len = 0;
-        if (FileName->Buffer)
-        {
-            pos = wcsrchr(FileName->Buffer, '\\');
-            len = wcslen(pos) * sizeof(WCHAR);
-            if (pos) snprintf(MI_PFN_CURRENT_PROCESS_NAME, min(16, len), "%S", pos);
-        }
+        pos = wcsrchr(FileName->Buffer, '\\');
+        len = wcslen(pos) * sizeof(WCHAR);
+        if (pos) snprintf(MI_PFN_CURRENT_PROCESS_NAME, min(16, len), "%S", pos);
+    }
 #endif
-        TempPte.u.Hard.PageFrameNumber = MiAllocatePfn(PointerPte, MM_EXECUTE);
 
-        /* Write it */
+    /* Loop the new driver PTEs */
+    TempPte = ValidKernelPte;
+    while (PointerPte < LastPte)
+    {
+        /* Make sure the PTE is not valid for whatever reason */
+        ASSERT(PointerPte->u.Hard.Valid == 0);
+
+        /* Grab a page */
+        PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
+
+        /* Initialize its PFN entry */
+        MiInitializePfn(PageFrameIndex, PointerPte, TRUE);
+
+        /* Write the PTE */
+        TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
         MI_WRITE_VALID_PTE(PointerPte, TempPte);
 
         /* Move on */
         PointerPte++;
     }
 
+    /* Release the PFN lock */
+    KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+
     /* Copy the image */
     RtlCopyMemory(DriverBase, Base, PteCount << PAGE_SHIFT);