Index: boot/freeldr/freeldr/mm/meminit.c
===================================================================
--- boot/freeldr/freeldr/mm/meminit.c	(revision 63961)
+++ boot/freeldr/freeldr/mm/meminit.c	(working copy)
@@ -1,7 +1,7 @@
 /*
  *  FreeLoader
  *  Copyright (C) 2006-2008     Aleksey Bragin  <aleksey@reactos.org>
- *  Copyright (C) 2006-2009     Hervé Poussineau  <hpoussin@reactos.org>
+ *  Copyright (C) 2006-2009     Hervï¿½ Poussineau  <hpoussin@reactos.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -75,6 +75,12 @@ AddMemoryDescriptor(
     TRACE("AddMemoryDescriptor(0x%lx-0x%lx [0x%lx pages])\n",
           BasePage, BasePage + PageCount, PageCount);
 
+    if (BasePage > (16 * 1024))
+        PageCount = 0;
+
+    if ((BasePage + PageCount) > (16 * 1024))
+        PageCount = (16 * 1024) - BasePage;
+
     /* Scan through all existing descriptors */
     for (i = 0, c = 0; (c < MaxCount) && (List[c].PageCount != 0); c++)
     {
Index: ntoskrnl/include/internal/mm.h
===================================================================
--- ntoskrnl/include/internal/mm.h	(revision 63961)
+++ ntoskrnl/include/internal/mm.h	(working copy)
@@ -373,6 +373,7 @@ extern MMPFNLIST MmZeroedPageListHead;
 extern MMPFNLIST MmFreePageListHead;
 extern MMPFNLIST MmStandbyPageListHead;
 extern MMPFNLIST MmModifiedPageListHead;
+extern MMPFNLIST MmModifiedPageListByColor[1];
 extern MMPFNLIST MmModifiedNoWritePageListHead;
 
 typedef struct _MM_MEMORY_CONSUMER
@@ -652,8 +653,27 @@ NTSTATUS
 NTAPI
 MiReadPageFile(
     _In_ PFN_NUMBER Page,
-    _In_ ULONG PageFileIndex,
-    _In_ ULONG_PTR PageFileOffset);
+    _In_ const MMPTE* PointerPte
+);
+
+NTSTATUS
+NTAPI
+MiWritePageFile(
+    _In_ PFN_NUMBER Page,
+    _In_ const MMPTE* PointerPte
+);
+
+VOID
+NTAPI
+MiFreePageFileEntry(
+    _In_ PMMPTE PointerPte
+);
+
+NTSTATUS
+NTAPI
+MiReservePageFileEntry(
+    _Out_ PMMPTE PointerPte
+);
 
 /* process.c ****************************************************************/
 
Index: ntoskrnl/mm/ARM3/miarm.h
===================================================================
--- ntoskrnl/mm/ARM3/miarm.h	(revision 63961)
+++ ntoskrnl/mm/ARM3/miarm.h	(working copy)
@@ -687,6 +687,7 @@ extern PKEVENT MiLowPagedPoolEvent;
 extern PKEVENT MiHighPagedPoolEvent;
 extern PKEVENT MiLowNonPagedPoolEvent;
 extern PKEVENT MiHighNonPagedPoolEvent;
+extern KEVENT MpwThreadEvent;
 extern PFN_NUMBER MmLowMemoryThreshold;
 extern PFN_NUMBER MmHighMemoryThreshold;
 extern PFN_NUMBER MiLowPagedPoolThreshold;
@@ -695,6 +696,7 @@ extern PFN_NUMBER MiLowNonPagedPoolThreshold;
 extern PFN_NUMBER MiHighNonPagedPoolThreshold;
 extern PFN_NUMBER MmMinimumFreePages;
 extern PFN_NUMBER MmPlentyFreePages;
+extern PFN_NUMBER MmTotalPagesForPagingFile;
 extern SIZE_T MmMinimumStackCommitInBytes;
 extern PFN_COUNT MiExpansionPoolPagesInitialCharge;
 extern PFN_NUMBER MmResidentAvailablePages;
Index: ntoskrnl/mm/ARM3/pagfault.c
===================================================================
--- ntoskrnl/mm/ARM3/pagfault.c	(revision 63961)
+++ ntoskrnl/mm/ARM3/pagfault.c	(working copy)
@@ -816,11 +816,10 @@ MiResolvePageFileFault(_In_ BOOLEAN StoreInstruction,
     ULONG Color;
     PFN_NUMBER Page;
     NTSTATUS Status;
-    MMPTE TempPte = *PointerPte;
-    KEVENT Event;
+    MMPTE PageFilePte = *PointerPte, TempPte;
     PMMPFN Pfn1;
-    ULONG PageFileIndex = TempPte.u.Soft.PageFileLow;
-    ULONG_PTR PageFileOffset = TempPte.u.Soft.PageFileHigh;
+
+    DPRINT1("Serving page fault for PTE %p (%u).\n", PointerPte, PageFilePte.u.Long);
 
     /* Things we don't support yet */
     ASSERT(CurrentProcess > HYDRA_PROCESS);
@@ -830,9 +829,9 @@ MiResolvePageFileFault(_In_ BOOLEAN StoreInstruction,
     ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
 
     /* Some sanity checks */
-    ASSERT(TempPte.u.Hard.Valid == 0);
-    ASSERT(TempPte.u.Soft.PageFileHigh != 0);
-    ASSERT(TempPte.u.Soft.PageFileHigh != MI_PTE_LOOKUP_NEEDED);
+    ASSERT(PageFilePte.u.Hard.Valid == 0);
+    ASSERT(PageFilePte.u.Soft.PageFileHigh != 0);
+    ASSERT(PageFilePte.u.Soft.PageFileHigh != MI_PTE_LOOKUP_NEEDED);
 
     /* Get any page, it will be overwritten */
     Color = MI_GET_NEXT_PROCESS_COLOR(CurrentProcess);
@@ -847,14 +846,13 @@ MiResolvePageFileFault(_In_ BOOLEAN StoreInstruction,
     ASSERT(Pfn1->u3.e1.ReadInProgress == 0);
     ASSERT(Pfn1->u3.e1.WriteInProgress == 0);
 
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-    Pfn1->u1.Event = &Event;
+    /* Set NULL event */
+    Pfn1->u1.Event = NULL;
     Pfn1->u3.e1.ReadInProgress = 1;
 
     /* We must write the PTE now as the PFN lock will be released while performing the IO operation */
+    TempPte.u.Long = 0;
     TempPte.u.Soft.Transition = 1;
-    TempPte.u.Soft.PageFileLow = 0;
-    TempPte.u.Soft.Prototype = 0;
     TempPte.u.Trans.PageFrameNumber = Page;
 
     MI_WRITE_INVALID_PTE(PointerPte, TempPte);
@@ -863,54 +861,63 @@ MiResolvePageFileFault(_In_ BOOLEAN StoreInstruction,
     KeReleaseQueuedSpinLock(LockQueuePfnLock, *OldIrql);
 
     /* Do the paging IO */
-    Status = MiReadPageFile(Page, PageFileIndex, PageFileOffset);
+    Status = MiReadPageFile(Page, &PageFilePte);
 
     /* Lock the PFN database again */
     *OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
 
     /* Nobody should have changed that while we were not looking */
-    ASSERT(Pfn1->u1.Event == &Event);
     ASSERT(Pfn1->u3.e1.ReadInProgress == 1);
     ASSERT(Pfn1->u3.e1.WriteInProgress == 0);
 
+    /* But maybe someone began waiting on us */
+    if (Pfn1->u1.Event != NULL)
+    {
+        /* Waiters gonna wait */
+        KeSetEvent(Pfn1->u1.Event, IO_NO_INCREMENT, FALSE);
+        Pfn1->u1.Event = NULL;
+    }
+
     if (!NT_SUCCESS(Status))
     {
         /* Malheur! */
         ASSERT(FALSE);
         Pfn1->u4.InPageError = 1;
         Pfn1->u1.ReadStatus = Status;
+        Status = STATUS_IN_PAGE_ERROR;
     }
 
     /* This is now a nice and normal PFN */
-    Pfn1->u1.Event = NULL;
     Pfn1->u3.e1.ReadInProgress = 0;
 
     /* And the PTE can finally be valid */
     MI_MAKE_HARDWARE_PTE(&TempPte, PointerPte, TempPte.u.Trans.Protection, Page);
     MI_WRITE_VALID_PTE(PointerPte, TempPte);
 
-    /* Waiters gonna wait */
-    KeSetEvent(&Event, IO_NO_INCREMENT, FALSE);
-
     return Status;
 }
 
 NTSTATUS
 NTAPI
-MiResolveTransitionFault(IN PVOID FaultingAddress,
-                         IN PMMPTE PointerPte,
-                         IN PEPROCESS CurrentProcess,
-                         IN KIRQL OldIrql,
-                         OUT PVOID *InPageBlock)
+MiResolveTransitionFault(
+    _In_ BOOLEAN StoreInstruction,
+    _In_ PVOID FaultingAddress,
+    _In_ PMMPTE PointerPte,
+    _In_ PEPROCESS CurrentProcess,
+    _In_ KIRQL OldIrql,
+    _In_ PVOID *InPageBlock)
 {
     PFN_NUMBER PageFrameIndex;
     PMMPFN Pfn1;
     MMPTE TempPte;
     PMMPTE PointerToPteForProtoPage;
-    DPRINT1("Transition fault on 0x%p with PTE 0x%p in process %s\n",
-            FaultingAddress, PointerPte, CurrentProcess->ImageFileName);
+    BOOLEAN MustWait = FALSE;
+    KEVENT IoEvent;
+
+    DPRINT("Transition fault on 0x%p with PTE 0x%p in process %s\n",
+            FaultingAddress, PointerPte, CurrentProcess ? CurrentProcess->ImageFileName : "Kernel");
 
-    /* Windowss does this check */
+    /* Windows does this check */
     ASSERT(*InPageBlock == NULL);
 
     /* ARM3 doesn't support this path */
@@ -936,15 +943,39 @@ MiResolveTransitionFault(IN PVOID FaultingAddress,
     /* See if we should wait before terminating the fault */
     if (Pfn1->u3.e1.ReadInProgress == 1)
     {
-    	DPRINT1("The page is currently being read!\n");
-    	ASSERT(Pfn1->u1.Event != NULL);
-    	*InPageBlock = Pfn1->u1.Event;
-    	if (PointerPte == Pfn1->PteAddress)
-    	{
-    	    DPRINT1("And this if for this particular PTE.\n");
-    	    /* The PTE will be made valid by the thread serving the fault */
-    	    return STATUS_SUCCESS; // FIXME: Maybe something more descriptive
-    	}
+        DPRINT1("The page is currently being read!\n");
+
+        ASSERT(Pfn1->u3.e1.WriteInProgress == 0);
+
+        KeInitializeEvent(&IoEvent, NotificationEvent, FALSE);
+        *InPageBlock = Pfn1->u1.Event;
+        Pfn1->u1.Event = &IoEvent;
+
+        MustWait = TRUE;
+
+        if (PointerPte == Pfn1->PteAddress)
+        {
+            DPRINT1("And this if for this particular PTE.\n");
+            /* The PTE will be made valid by the thread serving the page-in operation */
+            goto Quickie;
+        }
+    }
+
+    if (Pfn1->u3.e1.WriteInProgress == 1)
+    {
+        DPRINT1("The page is currently being written to!\n");
+
+        ASSERT(Pfn1->u3.e1.ReadInProgress == 0);
+
+        KeInitializeEvent(&IoEvent, NotificationEvent, FALSE);
+        *InPageBlock = Pfn1->u1.Event;
+        Pfn1->u1.Event = &IoEvent;
+
+        /* Mark it as modified if this is a store instruction,
+         * otherwise the data will already be on disk */
+        Pfn1->u3.e1.Modified = StoreInstruction;
+
+        MustWait = TRUE;
     }
 
     /* Windows checks there's some free pages and this isn't an in-page error */
@@ -1020,6 +1051,18 @@ MiResolveTransitionFault(IN PVOID FaultingAddress,
     /* Write the valid PTE */
     MI_WRITE_VALID_PTE(PointerPte, TempPte);
 
+Quickie:
+    if (MustWait)
+    {
+        /* Release the lock so the reader can finish */
+        KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+
+        /* Do the wait */
+        KeWaitForSingleObject(&IoEvent, WrPageIn, KernelMode, FALSE, NULL);
+
+        /* Callers expect the lock to still be held */
+        OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+    }
     /* Return success */
     return STATUS_PAGE_FAULT_TRANSITION;
 }
@@ -1125,7 +1168,8 @@ MiResolveProtoPteFault(IN BOOLEAN StoreInstruction,
     {
         /* Resolve the transition fault */
         ASSERT(OldIrql != MM_NOIRQL);
-        Status = MiResolveTransitionFault(Address,
+        Status = MiResolveTransitionFault(StoreInstruction,
+                                          Address,
                                           PointerProtoPte,
                                           Process,
                                           OldIrql,
@@ -1416,7 +1460,12 @@ MiDispatchFault(IN BOOLEAN StoreInstruction,
         LockIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
 
         /* Resolve */
-        Status = MiResolveTransitionFault(Address, PointerPte, Process, LockIrql, &InPageBlock);
+        Status = MiResolveTransitionFault(StoreInstruction,
+            Address,
+            PointerPte,
+            Process,
+            LockIrql,
+            &InPageBlock);
 
         NT_ASSERT(NT_SUCCESS(Status));
 
@@ -1425,8 +1474,8 @@ MiDispatchFault(IN BOOLEAN StoreInstruction,
 
         if (InPageBlock != NULL)
         {
-        	/* The page is being paged in by another process */
-        	KeWaitForSingleObject(InPageBlock, WrPageIn, KernelMode, FALSE, NULL);
+            /* We must wake the blocked threads */
+            KeSetEvent(InPageBlock, IO_NO_INCREMENT, FALSE);
         }
 
         ASSERT(OldIrql == KeGetCurrentIrql());
@@ -1821,9 +1870,6 @@ _WARN("Session space stuff is not implemented yet!")
         }
         else
         {
-            /* We don't implement transition PTEs */
-            ASSERT(TempPte.u.Soft.Transition == 0);
-
             /* Check for no-access PTE */
             if (TempPte.u.Soft.Protection == MM_NOACCESS)
             {
Index: ntoskrnl/mm/ARM3/pfnlist.c
===================================================================
--- ntoskrnl/mm/ARM3/pfnlist.c	(revision 63961)
+++ ntoskrnl/mm/ARM3/pfnlist.c	(working copy)
@@ -36,7 +36,7 @@ BOOLEAN MmMirroring;
 ULONG MmSystemPageColor;
 
 ULONG MmTransitionSharedPages;
-ULONG MmTotalPagesForPagingFile;
+PFN_NUMBER MmTotalPagesForPagingFile;
 
 MMPFNLIST MmZeroedPageListHead = {0, ZeroedPageList, LIST_HEAD, LIST_HEAD};
 MMPFNLIST MmFreePageListHead = {0, FreePageList, LIST_HEAD, LIST_HEAD};
@@ -288,6 +288,9 @@ MiUnlinkPageFromList(IN PMMPFN Pfn)
         ListHead->Total--;
         MmTotalPagesForPagingFile--;
 
+        if (MmTotalPagesForPagingFile == 0)
+            KeClearEvent(&MpwThreadEvent);
+
         /* Pick the correct colored list */
         ListHead = &MmModifiedPageListByColor[0];
 
@@ -477,6 +480,78 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex,
     return PageIndex;
 }
 
+static
+VOID
+NTAPI
+MiPopPageFromStandbyList(void)
+{
+    unsigned i;
+    PFN_NUMBER PageFrameIndex;
+    PMMPFN Pfn1;
+    PMMPTE PointerPte, SysPte, PteTable;
+    MMPTE PdePte;
+
+    /* Make sure PFN lock is held and we have pages */
+    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+    ASSERT(MmAvailablePages != 0);
+
+    /* This should be called in last resort if there are no more free pages */
+    ASSERT(MmZeroedPageListHead.Total == 0);
+    ASSERT(MmFreePageListHead.Total == 0);
+
+    /* Go by priority */
+    for (i = 0; i < 8; i++)
+    {
+        /* Get the oldest one */
+        PageFrameIndex = MmStandbyPageListByPriority[i].Blink;
+        if (PageFrameIndex != LIST_HEAD)
+            break;
+    }
+
+    /* There are no free pages but still available ones, so this must be here */
+    ASSERT(PageFrameIndex != LIST_HEAD);
+
+    /* Get the PFN */
+    Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
+
+    /* Sanity checks */
+    ASSERT(Pfn1->u3.e1.PageLocation == StandbyPageList);
+    ASSERT(Pfn1->u3.e1.Modified == 0);
+
+    /* Get a PTE to map the page directory */
+    SysPte = MiReserveSystemPtes(1, SystemPteSpace);
+    ASSERT(SysPte != NULL);
+
+    /* Build it */
+    MI_MAKE_HARDWARE_PTE_KERNEL(&PdePte,
+                                SysPte,
+                                MM_READWRITE,
+                                Pfn1->u4.PteFrame);
+    /* And map it */
+    MI_WRITE_VALID_PTE(SysPte, PdePte);
+    PteTable = MiPteToAddress(SysPte);
+
+    /* Finally get a pointer to the PTE this page represents */
+    PointerPte = &PteTable[MiAddressToPteOffset(MiPteToAddress(Pfn1->PteAddress))];
+
+    /* Other sanity checks */
+    ASSERT(PointerPte->u.Hard.Valid == 0);
+    ASSERT(PointerPte->u.Soft.Transition == 1);
+
+    /* Restore the PTE to its original value */
+    *PointerPte = Pfn1->OriginalPte;
+
+    /* We can get rid of this */
+    MiReleaseSystemPtes(SysPte, 1, SystemPteSpace);
+
+    /* And dereference the page table frame */
+    MiDecrementShareCount(MI_PFN_ELEMENT(Pfn1->u4.PteFrame), Pfn1->u4.PteFrame);
+
+    /* Unlink and insert it into the free list */
+    MiUnlinkPageFromList(Pfn1);
+    MiInsertPageInFreeList(PageFrameIndex);
+}
+
 PFN_NUMBER
 NTAPI
 MiRemoveAnyPage(IN ULONG Color)
@@ -489,6 +564,7 @@ MiRemoveAnyPage(IN ULONG Color)
     ASSERT(MmAvailablePages != 0);
     ASSERT(Color < MmSecondaryColors);
 
+again:
     /* Check the colored free list */
     PageIndex = MmFreePagesByColor[FreePageList][Color].Flink;
     if (PageIndex == LIST_HEAD)
@@ -510,8 +586,10 @@ MiRemoveAnyPage(IN ULONG Color)
                 ASSERT(PageIndex != LIST_HEAD);
                 if (PageIndex == LIST_HEAD)
                 {
-                    /* FIXME: Should check the standby list */
                     ASSERT(MmZeroedPageListHead.Total == 0);
+                    /* Pop one page from the standby list and try again */
+                    MiPopPageFromStandbyList();
+                    goto again;
                 }
             }
         }
@@ -546,6 +624,7 @@ MiRemoveZeroPage(IN ULONG Color)
     ASSERT(MmAvailablePages != 0);
     ASSERT(Color < MmSecondaryColors);
 
+again:
     /* Check the colored zero list */
     PageIndex = MmFreePagesByColor[ZeroedPageList][Color].Flink;
     if (PageIndex == LIST_HEAD)
@@ -570,8 +649,10 @@ MiRemoveZeroPage(IN ULONG Color)
                 ASSERT(PageIndex != LIST_HEAD);
                 if (PageIndex == LIST_HEAD)
                 {
-                    /* FIXME: Should check the standby list */
                     ASSERT(MmZeroedPageListHead.Total == 0);
+                    /* Pop one page from the standby list and try again */
+                    MiPopPageFromStandbyList();
+                    goto again;
                 }
             }
         }
@@ -860,6 +941,9 @@ MiInsertPageInList(IN PMMPFNLIST ListHead,
 
         /* Increment the number of paging file modified pages */
         MmTotalPagesForPagingFile++;
+
+        /* Wake the page writer thread */
+        KeSetEvent(&MpwThreadEvent, IO_NO_INCREMENT, FALSE);
     }
 
     /* Don't handle bad pages yet yet */
@@ -1060,6 +1144,9 @@ MiInitializePfn(IN PFN_NUMBER PageFrameIndex,
     ASSERT(PageFrameIndex != 0);
     Pfn1->u4.PteFrame = PageFrameIndex;
 
+    /* HACK until we get working sets rolling */
+    Pfn1->Wsle.u1.e1.Age = 0;
+
     /* Increase its share count so we don't get rid of it */
     Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
     Pfn1->u2.ShareCount++;
@@ -1270,32 +1357,8 @@ MiDecrementShareCount(IN PMMPFN Pfn1,
         /* PFN lock must be held */
         ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
 
-        if (Pfn1->u3.e2.ReferenceCount == 1)
-        {
-            /* Is there still a PFN for this page? */
-            if (MI_IS_PFN_DELETED(Pfn1) == TRUE)
-            {
-                /* Clear the last reference */
-                Pfn1->u3.e2.ReferenceCount = 0;
-                ASSERT(Pfn1->OriginalPte.u.Soft.Prototype == 0);
-
-                /* Mark the page temporarily as valid, we're going to make it free soon */
-                Pfn1->u3.e1.PageLocation = ActiveAndValid;
-
-                /* Bring it back into the free list */
-                MiInsertPageInFreeList(PageFrameIndex);
-            }
-            else
-            {
-                /* PFN not yet deleted, drop a ref count */
-                MiDecrementReferenceCount(Pfn1, PageFrameIndex);
-            }
-        }
-        else
-        {
-            /* Otherwise, just drop the reference count */
-            InterlockedDecrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount);
-        }
+        /* Drop a ref count */
+        MiDecrementReferenceCount(Pfn1, PageFrameIndex);
     }
 }
 
@@ -1338,6 +1401,13 @@ MiDecrementReferenceCount(IN PMMPFN Pfn1,
     /* Did someone set the delete flag? */
     if (MI_IS_PFN_DELETED(Pfn1))
     {
+        /* Did we have a Pagefile entry for it */
+        if ((Pfn1->OriginalPte.u.Soft.Prototype == 0)
+                && (Pfn1->OriginalPte.u.Soft.PageFileHigh != 0))
+        {
+            /* Yes. Set it free */
+            MiFreePageFileEntry(&Pfn1->OriginalPte);
+        }
         /* Insert it into the free list, there's nothing left to do */
         MiInsertPageInFreeList(PageFrameIndex);
         return;
Index: ntoskrnl/mm/ARM3/virtual.c
===================================================================
--- ntoskrnl/mm/ARM3/virtual.c	(revision 63961)
+++ ntoskrnl/mm/ARM3/virtual.c	(working copy)
@@ -407,9 +407,8 @@ MiDeletePte(IN PMMPTE PointerPte,
     /* See if the PTE is valid */
     if (TempPte.u.Hard.Valid == 0)
     {
-        /* Prototype and paged out PTEs not supported yet */
+        /* Prototype PTEs not supported yet */
         ASSERT(TempPte.u.Soft.Prototype == 0);
-        ASSERT((TempPte.u.Soft.PageFileHigh == 0) || (TempPte.u.Soft.Transition == 1));
 
         if (TempPte.u.Soft.Transition)
         {
@@ -446,6 +445,16 @@ MiDeletePte(IN PMMPTE PointerPte,
             }
             return;
         }
+
+        if (TempPte.u.Soft.PageFileHigh != 0)
+        {
+            /* Release the page file entry */
+            MiFreePageFileEntry(&TempPte);
+
+            /* And that's pretty much it */
+            MI_ERASE_PTE(PointerPte);
+            return;
+        }
     }
 
     /* Get the PFN entry */
Index: ntoskrnl/mm/balance.c
===================================================================
--- ntoskrnl/mm/balance.c	(revision 63961)
+++ ntoskrnl/mm/balance.c	(working copy)
@@ -362,9 +362,10 @@ MiBalancerThread(PVOID Unused)
    PVOID WaitObjects[2];
    NTSTATUS Status;
    ULONG i;
+   ULONG RandomSeed = 1;
 
-   WaitObjects[0] = &MiBalancerEvent;
-   WaitObjects[1] = &MiBalancerTimer;
+   WaitObjects[0] = &MiBalancerTimer;
+   WaitObjects[1] = &MiBalancerEvent;
 
    while (1)
    {
@@ -376,9 +377,100 @@ MiBalancerThread(PVOID Unused)
                                         FALSE,
                                         NULL,
                                         NULL);
+      if (Status == STATUS_WAIT_0)
+      {
+          /* For now, we only age the paged pool, with 100 randomly chosen addresses per run. */
+          unsigned Count = 100;
+          ULONG AddressRange = (ULONG_PTR)MmPagedPoolEnd - (ULONG_PTR)MmPagedPoolStart;
+          PVOID Address;
+          KIRQL OldIrql;
+          PMMPTE PointerPte;
+          PMMPDE PointerPde;
+          MMPTE TempPte;
+          PMMPFN Pfn1;
+          BOOLEAN Flush;
+
+          while (Count--)
+          {
+              /* Let's pretend this is random */
+              Address = (PVOID)((ULONG_PTR)MmPagedPoolStart + (RtlRandomEx(&RandomSeed) % AddressRange));
+
+              MiCheckPdeForPagedPool(Address);
+
+              /* Acquire PFN lock while we are cooking */
+              OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+
+              PointerPde = MiAddressToPde(Address);
+              if (PointerPde->u.Hard.Valid == 0)
+              {
+                  /* Bad luck, not a paged-in address */
+                  KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+                  continue;
+              }
+
+              PointerPte = MiAddressToPte(Address);
+              TempPte = *PointerPte;
+
+              if (TempPte.u.Hard.Valid == 0)
+              {
+                  /* Bad luck, not a paged-in address */
+                  KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+                  continue;
+              }
+
+              Flush = FALSE;
+
+              /* Get the Pfn */
+              Pfn1 = MI_PFN_ELEMENT(PFN_FROM_PTE(&TempPte));
+              ASSERT(Pfn1->PteAddress == PointerPte);
 
-      if (Status == STATUS_WAIT_0 || Status == STATUS_WAIT_1)
+              /* First check if it was written to */
+              if (TempPte.u.Hard.Dirty)
+                  Pfn1->u3.e1.Modified = 1;
+
+              /* See if it was accessed since the last time we looked */
+              if (TempPte.u.Hard.Accessed)
+              {
+                  /* Yes! Mark the page as young and fresh again */
+                  Pfn1->Wsle.u1.e1.Age = 0;
+                  /* Tell the CPU we want to know for the next time */
+                  TempPte.u.Hard.Accessed = 0;
+                  MI_UPDATE_VALID_PTE(PointerPte, TempPte);
+                  Flush = TRUE;
+              }
+              else if (Pfn1->Wsle.u1.e1.Age == 3)
+              {
+                  /* Page is getting old: Mark the PTE as transition */
+                  TempPte.u.Hard.Valid = 0;
+                  TempPte.u.Soft.Transition = 1;
+                  TempPte.u.Trans.Protection = Pfn1->OriginalPte.u.Soft.Protection;
+                  MiDecrementShareCount(Pfn1, PFN_FROM_PTE(&TempPte));
+                  MI_WRITE_INVALID_PTE(PointerPte, TempPte);
+                  Flush = TRUE;
+              }
+              else
+              {
+                  /* The page is just getting older */
+                  Pfn1->Wsle.u1.e1.Age++;
+              }
+
+              /* Flush the TLB entry if we have to */
+              if (Flush)
+              {
+#ifdef CONFIG_SMP
+                // FIXME: Should invalidate entry in every CPU TLB
+                ASSERT(FALSE);
+#endif
+                KeInvalidateTlbEntry(Address);
+              }
+
+              /* Unlock and go ahead finding another entry */
+              KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+          }
+      }
+      else if (Status == STATUS_WAIT_1)
       {
+        /* Balancer thread was woken up by legacy MM */
         ULONG InitialTarget = 0;
 
 #if (_MI_PAGING_LEVELS == 2)
Index: ntoskrnl/mm/mminit.c
===================================================================
--- ntoskrnl/mm/mminit.c	(revision 63961)
+++ ntoskrnl/mm/mminit.c	(working copy)
@@ -299,36 +299,172 @@ VOID
 NTAPI
 MmMpwThreadMain(PVOID Parameter)
 {
-   NTSTATUS Status;
-   ULONG PagesWritten;
-   LARGE_INTEGER Timeout;
-
-   UNREFERENCED_PARAMETER(Parameter);
-
-   Timeout.QuadPart = -50000000;
-
-   for(;;)
-   {
-      Status = KeWaitForSingleObject(&MpwThreadEvent,
-                                     0,
-                                     KernelMode,
-                                     FALSE,
-                                     &Timeout);
-      if (!NT_SUCCESS(Status))
-      {
-         DbgPrint("MpwThread: Wait failed\n");
-         KeBugCheck(MEMORY_MANAGEMENT);
-         return;
-      }
-
-      PagesWritten = 0;
-
-#ifndef NEWCC
-      // XXX arty -- we flush when evicting pages or destorying cache
-      // sections.
-      CcRosFlushDirtyPages(128, &PagesWritten, FALSE);
-#endif
-   }
+    NTSTATUS Status;
+    PVOID WaitObjects[2];
+    PMMPTE SysPte, PteTable;
+
+    WaitObjects[0] = &MpwThreadEvent;
+    WaitObjects[1] = MiLowMemoryEvent;
+
+    UNREFERENCED_PARAMETER(Parameter);
+
+    /* Reserve a PTE for the page table */
+    SysPte = MiReserveSystemPtes(1, SystemPteSpace);
+    ASSERT(SysPte != NULL);
+    PteTable = MiPteToAddress(SysPte);
+
+    for(;;)
+    {
+        /*
+         * To start working, we wait for two conditions:
+         *  - there are pages to be paged out.
+         *  - We are in a low memory situation.
+         */
+        Status = KeWaitForMultipleObjects(
+            2,
+            WaitObjects,
+            WaitAll,
+            WrPageOut,
+            KernelMode,
+            FALSE,
+            NULL,
+            NULL);
+
+        DPRINT1("THE KRAKEN WAS RELEASED AND WILL PAGE YOUR ASS OUT!\n");
+
+        if (NT_SUCCESS(Status))
+        {
+            KIRQL OldIrql;
+            PFN_NUMBER PageFrameIndex;
+            PMMPFN Pfn;
+            MMPTE TempPte, PdePte;
+            PMMPTE PointerPte;
+
+            /* Lock the PFN database */
+            OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+
+            /* The true main loop */
+            while ((MmTotalPagesForPagingFile != 0)
+                    && (MmAvailablePages < MmLowMemoryThreshold))
+            {
+                /* Get the first page from the list */
+                PageFrameIndex = MmModifiedPageListByColor[0].Flink;
+
+                /* Get The Pfn */
+                Pfn = MI_PFN_ELEMENT(PageFrameIndex);
+
+                /* Some things which must always hold */
+                ASSERT(Pfn->OriginalPte.u.Soft.Transition == 0);
+                ASSERT(Pfn->u3.ReferenceCount == 0);
+
+                /* And some that are not yet supported */
+                ASSERT(Pfn->OriginalPte.u.Soft.Prototype == 0);
+
+                TempPte.u.Long = 0;
+
+                /* Maybe this is not the first time */
+                if ((Pfn->OriginalPte.u.Soft.Prototype == 0) &&
+                        (Pfn->OriginalPte.u.Soft.PageFileHigh != 0))
+                {
+                    /* Use that */
+                    TempPte = Pfn->OriginalPte;
+                }
+                else
+                {
+                    MiReservePageFileEntry(&TempPte);
+                }
+
+                /* Get it out of the list and reference it */
+                MiUnlinkPageFromList(Pfn);
+                MiReferenceUnusedPageAndBumpLockCount(Pfn);
+
+                /* Mark it as write in progress */
+                Pfn->u3.e1.WriteInProgress = 1;
+                Pfn->u1.Event = NULL;
+
+                /* Release the PFN lock while we are writing */
+                KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+
+                /* Do the actual write */
+                Status = MiWritePageFile(PageFrameIndex, &TempPte);
+
+                /* Get the lock again */
+                OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+
+                /* We're done with this */
+                Pfn->u3.e1.WriteInProgress = 0;
+
+                /* Get a mapping to the page table */
+                MI_MAKE_HARDWARE_PTE_KERNEL(&PdePte,
+                                            SysPte,
+                                            MM_READWRITE,
+                                            Pfn->u4.PteFrame);
+                MI_WRITE_VALID_PTE(SysPte, PdePte);
+
+                /* Finally get a pointer to the PTE this page represents */
+                PointerPte = &PteTable[MiAddressToPteOffset(MiPteToAddress(Pfn->PteAddress))];
+
+                /* Get relevant values from the original PTE */
+                TempPte.u.Soft.Protection = PointerPte->u.Soft.Protection;
+
+                /* Maybe someone tried to access the page while we were not looking */
+                if (Pfn->u1.Event != NULL)
+                {
+                    DPRINT1("Page fault occured while we were paging out!\n");
+
+                    /* So the soft page fault put the page in valid state again */
+                    ASSERT(Pfn->u3.e1.PageLocation == ActiveAndValid);
+
+                    /* Save the pagefile entry for this page, and move along */
+                    Pfn->OriginalPte = TempPte;
+                    KeSetEvent(Pfn->u1.Event, IO_NO_INCREMENT, FALSE);
+                    /* Bump the reference count */
+                    Pfn->u3.e2.ReferenceCount++;
+                }
+                else if (!NT_SUCCESS(Status))
+                {
+                    DPRINT1("Failed to write page to pagefile!\n");
+                    /* This is now useless */
+                    MiFreePageFileEntry(&TempPte);
+                    /* MiDereferencePfnAndDropLockCount will put it back on the list */
+                }
+                else
+                {
+                    DPRINT1("Page %x successfully paged out!\n", PageFrameIndex);
+
+                    /* Of course it must already be invalid */
+                    ASSERT(PointerPte->u.Hard.Valid == 0);
+
+                    /* And be in transition */
+                    ASSERT(PointerPte->u.Soft.Transition == 1);
+
+                    /* So the PTE is now officially paged out */
+                    MI_WRITE_INVALID_PTE(PointerPte, TempPte);
+
+                    /* And dereference the page table frame */
+                    MiDecrementShareCount(MI_PFN_ELEMENT(Pfn->u4.PteFrame), Pfn->u4.PteFrame);
+                    /* We can finally make it available for real */
+                    MI_SET_PFN_DELETED(Pfn);
+                }
+
+                /* This will put it back in the free list */
+                MiDereferencePfnAndDropLockCount(Pfn);
+
+                /* Unmap the Page Table */
+                MI_ERASE_PTE(SysPte);
+                KeInvalidateTlbEntry(PteTable);
+            }
+
+            /* We're done for this run */
+            KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+        }
+        else
+        {
+            DPRINT1("MpwThread: Wait failed\n");
+            KeBugCheck(MEMORY_MANAGEMENT);
+            return;
+        }
+    }
 }
 
 NTSTATUS
Index: ntoskrnl/mm/pagefile.c
===================================================================
--- ntoskrnl/mm/pagefile.c	(revision 63961)
+++ ntoskrnl/mm/pagefile.c	(working copy)
@@ -73,9 +73,6 @@ RETRIEVEL_DESCRIPTOR_LIST, *PRETRIEVEL_DESCRIPTOR_LIST;
 /* List of paging files, both used and free */
 static PPAGINGFILE PagingFileList[MAX_PAGING_FILES];
 
-/* Lock for examining the list of paging files */
-static KSPIN_LOCK PagingFileListLock;
-
 /* Number of paging files */
 ULONG MmNumberOfPagingFiles;
 
@@ -221,57 +218,12 @@ NTSTATUS
 NTAPI
 MmWriteToSwapPage(SWAPENTRY SwapEntry, PFN_NUMBER Page)
 {
-   ULONG i;
-   ULONG_PTR offset;
-   LARGE_INTEGER file_offset;
-   IO_STATUS_BLOCK Iosb;
-   NTSTATUS Status;
-   KEVENT Event;
-   UCHAR MdlBase[sizeof(MDL) + sizeof(ULONG)];
-   PMDL Mdl = (PMDL)MdlBase;
+    MMPTE TempPte;
 
-   DPRINT("MmWriteToSwapPage\n");
-
-   if (SwapEntry == 0)
-   {
-      KeBugCheck(MEMORY_MANAGEMENT);
-      return(STATUS_UNSUCCESSFUL);
-   }
-
-   i = FILE_FROM_ENTRY(SwapEntry);
-   offset = OFFSET_FROM_ENTRY(SwapEntry);
-
-   if (PagingFileList[i]->FileObject == NULL ||
-         PagingFileList[i]->FileObject->DeviceObject == NULL)
-   {
-      DPRINT1("Bad paging file 0x%.8X\n", SwapEntry);
-      KeBugCheck(MEMORY_MANAGEMENT);
-   }
-
-   MmInitializeMdl(Mdl, NULL, PAGE_SIZE);
-   MmBuildMdlFromPages(Mdl, &Page);
-   Mdl->MdlFlags |= MDL_PAGES_LOCKED;
-
-   file_offset.QuadPart = offset * PAGE_SIZE;
-   file_offset = MmGetOffsetPageFile(PagingFileList[i]->RetrievalPointers, file_offset);
-
-   KeInitializeEvent(&Event, NotificationEvent, FALSE);
-   Status = IoSynchronousPageWrite(PagingFileList[i]->FileObject,
-                                   Mdl,
-                                   &file_offset,
-                                   &Event,
-                                   &Iosb);
-   if (Status == STATUS_PENDING)
-   {
-      KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
-      Status = Iosb.Status;
-   }
-
-   if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
-   {
-      MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl);
-   }
-   return(Status);
+    TempPte.u.Long = 0;
+    TempPte.u.Soft.PageFileHigh = OFFSET_FROM_ENTRY(SwapEntry);
+    TempPte.u.Soft.PageFileLow = FILE_FROM_ENTRY(SwapEntry);
+    return MiWritePageFile(Page, &TempPte);
 }
 
 
@@ -279,18 +231,25 @@ NTSTATUS
 NTAPI
 MmReadFromSwapPage(SWAPENTRY SwapEntry, PFN_NUMBER Page)
 {
-	return MiReadPageFile(Page, FILE_FROM_ENTRY(SwapEntry), OFFSET_FROM_ENTRY(SwapEntry));
+    MMPTE TempPte;
+
+    TempPte.u.Long = 0;
+    TempPte.u.Soft.PageFileHigh = OFFSET_FROM_ENTRY(SwapEntry);
+    TempPte.u.Soft.PageFileLow = FILE_FROM_ENTRY(SwapEntry);
+	return MiReadPageFile(Page, &TempPte);
 }
 
 NTSTATUS
 NTAPI
 MiReadPageFile(
 	_In_ PFN_NUMBER Page,
-	_In_ ULONG PageFileIndex,
-	_In_ ULONG_PTR PageFileOffset)
+	_In_ const MMPTE* PointerPte
+)
 {
-   LARGE_INTEGER file_offset;
+   LARGE_INTEGER FileOffset;
    IO_STATUS_BLOCK Iosb;
+   ULONG PageFileIndex = PointerPte->u.Soft.PageFileLow;
+   ULONG_PTR PageFileOffset = PointerPte->u.Soft.PageFileHigh;
    NTSTATUS Status;
    KEVENT Event;
    UCHAR MdlBase[sizeof(MDL) + sizeof(ULONG)];
@@ -305,6 +264,9 @@ MiReadPageFile(
       return(STATUS_UNSUCCESSFUL);
    }
 
+   /* Normalize it */
+   PageFileOffset--;
+
    ASSERT(PageFileIndex < MAX_PAGING_FILES);
 
    PagingFile = PagingFileList[PageFileIndex];
@@ -319,13 +281,13 @@ MiReadPageFile(
    MmBuildMdlFromPages(Mdl, &Page);
    Mdl->MdlFlags |= MDL_PAGES_LOCKED;
 
-   file_offset.QuadPart = PageFileOffset * PAGE_SIZE;
-   file_offset = MmGetOffsetPageFile(PagingFile->RetrievalPointers, file_offset);
+   FileOffset.QuadPart = PageFileOffset * PAGE_SIZE;
+   FileOffset = MmGetOffsetPageFile(PagingFile->RetrievalPointers, FileOffset);
 
    KeInitializeEvent(&Event, NotificationEvent, FALSE);
    Status = IoPageRead(PagingFile->FileObject,
                        Mdl,
-                       &file_offset,
+                       &FileOffset,
                        &Event,
                        &Iosb);
    if (Status == STATUS_PENDING)
@@ -340,124 +302,247 @@ MiReadPageFile(
    return(Status);
 }
 
+NTSTATUS
+NTAPI
+MiWritePageFile(
+    _In_ PFN_NUMBER Page,
+    _In_ const MMPTE* PointerPte
+)
+{
+    ULONG PageFileIndex = PointerPte->u.Soft.PageFileLow;
+    ULONG_PTR PageFileOffset = PointerPte->u.Soft.PageFileHigh;
+    LARGE_INTEGER FileOffset;
+    IO_STATUS_BLOCK Iosb;
+    NTSTATUS Status;
+    KEVENT Event;
+    UCHAR MdlBase[sizeof(MDL) + sizeof(ULONG)];
+    PMDL Mdl = (PMDL) MdlBase;
+    PPAGINGFILE PagingFile;
+
+    /* The PTE must already be setup to point to a pagefile entry */
+    ASSERT(PointerPte->u.Hard.Valid == 0);
+    ASSERT(PointerPte->u.Soft.Transition == 0);
+    ASSERT(PointerPte->u.Soft.Prototype == 0);
+
+    DPRINT("MiWriteSwapFile\n");
+
+    if (PageFileOffset == 0)
+    {
+        KeBugCheck(MEMORY_MANAGEMENT);
+        return (STATUS_UNSUCCESSFUL);
+    }
+
+    /* Normalize it */
+    PageFileOffset--;
+
+    ASSERT(PageFileIndex < MAX_PAGING_FILES);
+
+    PagingFile = PagingFileList[PageFileIndex];
+
+    if (PagingFile->FileObject == NULL || PagingFile->FileObject->DeviceObject == NULL)
+    {
+        DPRINT1("Bad paging file %u\n", PageFileIndex);
+        KeBugCheck(MEMORY_MANAGEMENT);
+    }
+
+    MmInitializeMdl(Mdl, NULL, PAGE_SIZE);
+    MmBuildMdlFromPages(Mdl, &Page);
+    Mdl->MdlFlags |= MDL_PAGES_LOCKED;
+
+    FileOffset.QuadPart = PageFileOffset * PAGE_SIZE;
+    FileOffset = MmGetOffsetPageFile(PagingFile->RetrievalPointers, FileOffset);
+
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+    Status = IoSynchronousPageWrite(PagingFile->FileObject,
+                                    Mdl,
+                                    &FileOffset,
+                                    &Event,
+                                    &Iosb);
+    if (Status == STATUS_PENDING)
+    {
+        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+        Status = Iosb.Status;
+    }
+    if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
+    {
+        MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
+    }
+    return Status;
+}
+
 VOID
-INIT_FUNCTION
 NTAPI
-MmInitPagingFile(VOID)
+MiFreePageFileEntry(
+    _In_ PMMPTE PointerPte
+)
 {
-   ULONG i;
+    ULONG PageFileIndex;
+    ULONG_PTR PageFileOffset, MapOffset;
+    PPAGINGFILE PageFile;
+    ULONG BitSet;
 
-   KeInitializeSpinLock(&PagingFileListLock);
+    /* Some sanity checks */
+    ASSERT(PointerPte->u.Hard.Valid == 0);
+    ASSERT(PointerPte->u.Soft.Transition == 0);
+    ASSERT(PointerPte->u.Soft.Prototype == 0);
 
-   MiFreeSwapPages = 0;
-   MiUsedSwapPages = 0;
-   MiReservedSwapPages = 0;
+    /* We must hold the PFN lock */
+    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
 
-   for (i = 0; i < MAX_PAGING_FILES; i++)
-   {
-      PagingFileList[i] = NULL;
-   }
-   MmNumberOfPagingFiles = 0;
+    PageFileIndex = PointerPte->u.Soft.PageFileLow;
+    PageFileOffset = PointerPte->u.Soft.PageFileHigh - 1;
+    MapOffset = PageFileOffset >> 5;
+    BitSet = 1 << (PageFileOffset & 0x1F);
+
+    DPRINT1("Releasing page file entry %u, %lu\n", PageFileIndex, PageFileOffset);
+
+    ASSERT(PageFileIndex < MAX_PAGING_FILES);
+
+    PageFile = PagingFileList[PageFileIndex];
+
+    /* And also lock this pagefile */
+    KeAcquireSpinLockAtDpcLevel(&PageFile->AllocMapLock);
+
+    /* It must be already in use */
+    ASSERT(PageFile->AllocMap[MapOffset] & BitSet);
+    PageFile->AllocMap[MapOffset] ^= BitSet;
+
+    /* One more */
+    PageFile->FreePages++;
+    PageFile->UsedPages--;
+
+    MiFreeSwapPages++;
+    MiUsedSwapPages--;
+
+    /* Done */
+    KeReleaseSpinLockFromDpcLevel(&PageFile->AllocMapLock);
 }
 
-static ULONG
-MiAllocPageFromPagingFile(PPAGINGFILE PagingFile)
+NTSTATUS
+NTAPI
+MiReservePageFileEntry(
+    _Out_ PMMPTE PointerPte
+)
 {
-   KIRQL oldIrql;
-   ULONG i, j;
+    ULONG PageFileIndex;
+    ULONG_PTR PageFileOffset = ~1, MapOffset;
+    PPAGINGFILE PageFile;
 
-   KeAcquireSpinLock(&PagingFile->AllocMapLock, &oldIrql);
+    /* We must hold the PFN lock */
+    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
 
-   for (i = 0; i < PagingFile->AllocMapSize; i++)
-   {
-      for (j = 0; j < 32; j++)
-      {
-         if (!(PagingFile->AllocMap[i] & (1 << j)))
-         {
-            PagingFile->AllocMap[i] |= (1 << j);
-            PagingFile->UsedPages++;
-            PagingFile->FreePages--;
-            KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql);
-            return((i * 32) + j);
-         }
-      }
-   }
+    for (PageFileIndex = 0; PageFileIndex < MAX_PAGING_FILES; PageFileIndex++)
+    {
+        if (PagingFileList[PageFileIndex] == NULL)
+            continue;
+        if (PagingFileList[PageFileIndex]->FreePages != 0)
+            break;
+    }
+
+    if (PageFileIndex == MAX_PAGING_FILES)
+    {
+        DPRINT1("Pagefiles are full!\n");
+        return STATUS_PAGEFILE_QUOTA;
+    }
 
-   KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql);
-   return(0xFFFFFFFF);
+    PageFile = PagingFileList[PageFileIndex];
+
+    /* And also lock this page */
+    KeAcquireSpinLockAtDpcLevel(&PageFile->AllocMapLock);
+
+    /* Find a free entry in this page file */
+    // FIXME: Use a bitmap...
+    for (MapOffset = 0; MapOffset < PageFile->AllocMapSize; MapOffset++)
+    {
+        unsigned j;
+        PULONG BitSet = &PageFile->AllocMap[MapOffset];
+        for (j = 0; j < 32; j++)
+        {
+            if ((*BitSet & (1 << j)) == 0)
+            {
+                /* Mark it as being in use */
+                *BitSet |= (1 << j);
+                break;
+            }
+        }
+
+        if (j != 32)
+        {
+            PageFileOffset = (MapOffset << 5) | j;
+            break;
+        }
+    }
+
+    /* We must have found something as the file was marked as having free entries */
+    ASSERT(PageFileOffset != ~1);
+
+    DPRINT1("Reserving page file entry %u, %lu\n", PageFileIndex, PageFileOffset);
+
+    /* Done */
+    KeReleaseSpinLockFromDpcLevel(&PageFile->AllocMapLock);
+
+    /* We rely on PageFileHigh being != 0 */
+    PointerPte->u.Soft.PageFileHigh = PageFileOffset + 1;
+    PointerPte->u.Soft.PageFileLow = PageFileIndex;
+
+    return STATUS_SUCCESS;
 }
 
 VOID
+INIT_FUNCTION
 NTAPI
-MmFreeSwapPage(SWAPENTRY Entry)
+MmInitPagingFile(VOID)
 {
    ULONG i;
-   ULONG_PTR off;
-   KIRQL oldIrql;
 
-   i = FILE_FROM_ENTRY(Entry);
-   off = OFFSET_FROM_ENTRY(Entry);
+   MiFreeSwapPages = 0;
+   MiUsedSwapPages = 0;
+   MiReservedSwapPages = 0;
 
-   KeAcquireSpinLock(&PagingFileListLock, &oldIrql);
-   if (PagingFileList[i] == NULL)
+   for (i = 0; i < MAX_PAGING_FILES; i++)
    {
-      KeBugCheck(MEMORY_MANAGEMENT);
+      PagingFileList[i] = NULL;
    }
-   KeAcquireSpinLockAtDpcLevel(&PagingFileList[i]->AllocMapLock);
-
-   PagingFileList[i]->AllocMap[off >> 5] &= (~(1 << (off % 32)));
+   MmNumberOfPagingFiles = 0;
+}
 
-   PagingFileList[i]->FreePages++;
-   PagingFileList[i]->UsedPages--;
+VOID
+NTAPI
+MmFreeSwapPage(SWAPENTRY Entry)
+{
+    MMPTE TempPte;
+    KIRQL OldIrql;
 
-   MiFreeSwapPages++;
-   MiUsedSwapPages--;
+    TempPte.u.Long = 0;
+    TempPte.u.Soft.PageFileLow = FILE_FROM_ENTRY(Entry);
+    TempPte.u.Soft.PageFileHigh = OFFSET_FROM_ENTRY(Entry);
 
-   KeReleaseSpinLockFromDpcLevel(&PagingFileList[i]->AllocMapLock);
-   KeReleaseSpinLock(&PagingFileListLock, oldIrql);
+    OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+    MiFreePageFileEntry(&TempPte);
+    KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
 }
 
 SWAPENTRY
 NTAPI
 MmAllocSwapPage(VOID)
 {
-   KIRQL oldIrql;
-   ULONG i;
-   ULONG off;
-   SWAPENTRY entry;
+    MMPTE TempPte;
+    SWAPENTRY entry;
+    NTSTATUS Status;
+    KIRQL OldIrql;
 
-   KeAcquireSpinLock(&PagingFileListLock, &oldIrql);
+    TempPte.u.Long = 0;
 
-   if (MiFreeSwapPages == 0)
-   {
-      KeReleaseSpinLock(&PagingFileListLock, oldIrql);
-      return(0);
-   }
+    OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+    Status = MiReservePageFileEntry(&TempPte);
+    KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
 
-   for (i = 0; i < MAX_PAGING_FILES; i++)
-   {
-      if (PagingFileList[i] != NULL &&
-            PagingFileList[i]->FreePages >= 1)
-      {
-         off = MiAllocPageFromPagingFile(PagingFileList[i]);
-         if (off == 0xFFFFFFFF)
-         {
-            KeBugCheck(MEMORY_MANAGEMENT);
-            KeReleaseSpinLock(&PagingFileListLock, oldIrql);
-            return(STATUS_UNSUCCESSFUL);
-         }
-         MiUsedSwapPages++;
-         MiFreeSwapPages--;
-         KeReleaseSpinLock(&PagingFileListLock, oldIrql);
+    if (!NT_SUCCESS(Status))
+        return 0;
 
-         entry = ENTRY_FROM_FILE_OFFSET(i, off);
-         return(entry);
-      }
-   }
+    entry = ENTRY_FROM_FILE_OFFSET(TempPte.u.Soft.PageFileLow, TempPte.u.Soft.PageFileHigh);
 
-   KeReleaseSpinLock(&PagingFileListLock, oldIrql);
-   KeBugCheck(MEMORY_MANAGEMENT);
-   return(0);
+    return entry;
 }
 
 static PRETRIEVEL_DESCRIPTOR_LIST FASTCALL
@@ -488,7 +573,7 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
    IO_STATUS_BLOCK IoStatus;
    PFILE_OBJECT FileObject;
    PPAGINGFILE PagingFile;
-   KIRQL oldIrql;
+   KIRQL OldIrql;
    ULONG AllocMapSize;
    FILE_FS_SIZE_INFORMATION FsSizeInformation;
    PRETRIEVEL_DESCRIPTOR_LIST RetDescList;
@@ -799,7 +884,7 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
       PagingFile->RetrievalPointers->Extents[i].NextVcn.QuadPart *= BytesPerAllocationUnit;
    }
 
-   KeAcquireSpinLock(&PagingFileListLock, &oldIrql);
+   OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
    for (i = 0; i < MAX_PAGING_FILES; i++)
    {
       if (PagingFileList[i] == NULL)
@@ -810,7 +895,7 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
    }
    MiFreeSwapPages = MiFreeSwapPages + PagingFile->FreePages;
    MmNumberOfPagingFiles++;
-   KeReleaseSpinLock(&PagingFileListLock, oldIrql);
+   KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
 
    ZwClose(FileHandle);
 
