[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / mm / section.c
index bc3533f..1a71d66 100644 (file)
@@ -127,6 +127,7 @@ typedef struct
    BOOLEAN WasDirty;
    BOOLEAN Private;
    PEPROCESS CallingProcess;
+   ULONG_PTR SectionEntry;
 }
 MM_SECTION_PAGEOUT_CONTEXT;
 
@@ -167,15 +168,6 @@ static GENERIC_MAPPING MmpSectionMapping = {
          STANDARD_RIGHTS_EXECUTE | SECTION_MAP_EXECUTE,
          SECTION_ALL_ACCESS};
 
-#define PAGE_FROM_SSE(E)         ((E) & 0xFFFFF000)
-#define PFN_FROM_SSE(E)          ((E) >> PAGE_SHIFT)
-#define SHARE_COUNT_FROM_SSE(E)  (((E) & 0x00000FFC) >> 2)
-#define IS_SWAP_FROM_SSE(E)      ((E) & 0x00000001)
-#define MAX_SHARE_COUNT          0x3FF
-#define MAKE_SSE(P, C)           ((P) | ((C) << 2))
-#define SWAPENTRY_FROM_SSE(E)    ((E) >> 1)
-#define MAKE_SWAP_SSE(S)         (((ULONG)(S) << 1) | 0x1)
-
 static const INFORMATION_CLASS_INFO ExSectionInfoClass[] =
 {
   ICI_SQ_SAME( sizeof(SECTION_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* SectionBasicInformation */
@@ -695,7 +687,7 @@ l_ReadHeaderFromFile:
         pssSegments[i].Image.Characteristics = pishSectionHeaders[i].Characteristics;
 
         /* ensure the memory image is no larger than 4GB */
-        nPrevVirtualEndOfSegment = pssSegments[i].Image.VirtualAddress + pssSegments[i].Length.QuadPart;
+        nPrevVirtualEndOfSegment = (ULONG_PTR)(pssSegments[i].Image.VirtualAddress + pssSegments[i].Length.QuadPart);
         if (nPrevVirtualEndOfSegment < pssSegments[i].Image.VirtualAddress)
             DIE(("The image is too large\n"));
     }
@@ -713,43 +705,6 @@ l_Return:
     return nStatus;
 }
 
-/* Note: Mmsp prefix denotes "Memory Manager Section Private". */
-
-/*
- * FUNCTION:  Waits in kernel mode up to ten seconds for an MM_PAGEOP event.
- * ARGUMENTS: PMM_PAGEOP which event we should wait for.
- * RETURNS:   Status of the wait.
- */
-static NTSTATUS
-MmspWaitForPageOpCompletionEvent(PMM_PAGEOP PageOp)
-{
-   LARGE_INTEGER Timeout;
-#ifdef __GNUC__ /* TODO: Use other macro to check for suffix to use? */
-
-   Timeout.QuadPart = -100000000LL; // 10 sec
-#else
-
-   Timeout.QuadPart = -100000000; // 10 sec
-#endif
-
-   return KeWaitForSingleObject(&PageOp->CompletionEvent, 0, KernelMode, FALSE, &Timeout);
-}
-
-
-/*
- * FUNCTION:  Sets the page op completion event and releases the page op.
- * ARGUMENTS: PMM_PAGEOP.
- * RETURNS:   In shorter time than it takes you to even read this
- *            description, so don't even think about geting a mug of coffee.
- */
-static void
-MmspCompleteAndReleasePageOp(PMM_PAGEOP PageOp)
-{
-   KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
-   MmReleasePageOp(PageOp);
-}
-
-
 /*
  * FUNCTION:  Waits in kernel mode indefinitely for a file object lock.
  * ARGUMENTS: PFILE_OBJECT to wait for.
@@ -813,7 +768,7 @@ NTAPI
 MmSharePageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
                                PLARGE_INTEGER Offset)
 {
-   ULONG Entry;
+   ULONG_PTR Entry;
 
    Entry = MmGetPageEntrySectionSegment(Segment, Offset);
    if (Entry == 0)
@@ -840,12 +795,12 @@ MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section,
                                  PMM_SECTION_SEGMENT Segment,
                                  PLARGE_INTEGER Offset,
                                  BOOLEAN Dirty,
-                                 BOOLEAN PageOut)
+                                 BOOLEAN PageOut,
+                                 ULONG_PTR *InEntry)
 {
-   ULONG Entry;
+   ULONG_PTR Entry = InEntry ? *InEntry : MmGetPageEntrySectionSegment(Segment, Offset);
    BOOLEAN IsDirectMapped = FALSE;
 
-   Entry = MmGetPageEntrySectionSegment(Segment, Offset);
    if (Entry == 0)
    {
       DPRINT1("Entry == 0 for MmUnsharePageEntrySectionSegment\n");
@@ -853,7 +808,7 @@ MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section,
    }
    if (SHARE_COUNT_FROM_SSE(Entry) == 0)
    {
-      DPRINT1("Zero share count for unshare\n");
+       DPRINT1("Zero share count for unshare (Seg %p Offset %x Page %x)\n", Segment, Offset->LowPart, PFN_FROM_SSE(Entry));
        KeBugCheck(MEMORY_MANAGEMENT);
    }
    if (IS_SWAP_FROM_SSE(Entry))
@@ -922,10 +877,14 @@ MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section,
              *   page without a rmap entry.
              */
             MmSetPageEntrySectionSegment(Segment, Offset, Entry);
+            if (InEntry) *InEntry = Entry;
+            MiSetPageEvent(NULL, NULL);
          }
          else
          {
             MmSetPageEntrySectionSegment(Segment, Offset, 0);
+            if (InEntry) *InEntry = 0;
+            MiSetPageEvent(NULL, NULL);
             if (!IsDirectMapped)
             {
                MmReleasePageMemoryConsumer(MC_USER, Page);
@@ -955,7 +914,9 @@ MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section,
                   }
                }
                MmSetPageEntrySectionSegment(Segment, Offset, MAKE_SWAP_SSE(SavedSwapEntry));
+               if (InEntry) *InEntry = MAKE_SWAP_SSE(SavedSwapEntry);
                MmSetSavedSwapEntryPage(Page, 0);
+               MiSetPageEvent(NULL, NULL);
             }
             MmReleasePageMemoryConsumer(MC_USER, Page);
          }
@@ -968,7 +929,10 @@ MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section,
    }
    else
    {
-      MmSetPageEntrySectionSegment(Segment, Offset, Entry);
+      if (InEntry)
+          *InEntry = Entry;
+      else
+          MmSetPageEntrySectionSegment(Segment, Offset, Entry);
    }
    return(SHARE_COUNT_FROM_SSE(Entry) > 0);
 }
@@ -982,7 +946,7 @@ BOOLEAN MiIsPageFromCache(PMEMORY_AREA MemoryArea,
       PBCB Bcb;
       PCACHE_SEGMENT CacheSeg;
       Bcb = MemoryArea->Data.SectionData.Section->FileObject->SectionObjectPointer->SharedCacheMap;
-      CacheSeg = CcRosLookupCacheSegment(Bcb, SegOffset + MemoryArea->Data.SectionData.Segment->Image.FileOffset);
+      CacheSeg = CcRosLookupCacheSegment(Bcb, (ULONG)(SegOffset + MemoryArea->Data.SectionData.Segment->Image.FileOffset));
       if (CacheSeg)
       {
          CcRosReleaseCacheSegment(Bcb, CacheSeg, CacheSeg->Valid, FALSE, TRUE);
@@ -995,22 +959,24 @@ BOOLEAN MiIsPageFromCache(PMEMORY_AREA MemoryArea,
 
 NTSTATUS
 NTAPI
-MiCopyFromUserPage(PFN_NUMBER DestPage, PVOID SourceAddress)
+MiCopyFromUserPage(PFN_NUMBER DestPage, PFN_NUMBER SrcPage)
 {
     PEPROCESS Process;
-    KIRQL Irql;
-    PVOID TempAddress;
+    KIRQL Irql, Irql2;
+    PVOID DestAddress, SrcAddress;
 
-    ASSERT((ULONG_PTR)SourceAddress % PAGE_SIZE == 0);
     Process = PsGetCurrentProcess();
-    TempAddress = MiMapPageInHyperSpace(Process, DestPage, &Irql);
-    if (TempAddress == NULL)
+    DestAddress = MiMapPageInHyperSpace(Process, DestPage, &Irql);
+    SrcAddress = MiMapPageInHyperSpace(Process, SrcPage, &Irql2);
+    if (DestAddress == NULL || SrcAddress == NULL)
     {
         return(STATUS_NO_MEMORY);
     }
-    ASSERT((ULONG_PTR)TempAddress % PAGE_SIZE == 0);
-    RtlCopyMemory(TempAddress, SourceAddress, PAGE_SIZE);
-    MiUnmapPageInHyperSpace(Process, TempAddress, Irql);
+    ASSERT((ULONG_PTR)DestAddress % PAGE_SIZE == 0);
+    ASSERT((ULONG_PTR)SrcAddress % PAGE_SIZE == 0);
+    RtlCopyMemory(DestAddress, SrcAddress, PAGE_SIZE);
+    MiUnmapPageInHyperSpace(Process, SrcAddress, Irql2);
+    MiUnmapPageInHyperSpace(Process, DestAddress, Irql);
     return(STATUS_SUCCESS);
 }
 
@@ -1029,7 +995,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
  */
 {
    ULONG BaseOffset;
-   ULONG_PTR FileOffset;
+   ULONGLONG FileOffset;
    PVOID BaseAddress;
    BOOLEAN UptoDate;
    PCACHE_SEGMENT CacheSeg;
@@ -1042,7 +1008,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
 
    FileObject = MemoryArea->Data.SectionData.Section->FileObject;
    Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
-   RawLength = MemoryArea->Data.SectionData.Segment->RawLength.QuadPart;
+   RawLength = (ULONG_PTR)(MemoryArea->Data.SectionData.Segment->RawLength.QuadPart);
    FileOffset = SegOffset + MemoryArea->Data.SectionData.Segment->Image.FileOffset;
    IsImageSection = MemoryArea->Data.SectionData.Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
 
@@ -1055,8 +1021,8 @@ MiReadPage(PMEMORY_AREA MemoryArea,
     * memory area was mapped at an offset in the file which is page aligned
     * then get the related cache segment.
     */
-   if ((FileOffset % PAGE_SIZE) == 0 &&
-       (SegOffset + PAGE_SIZE <= RawLength || !IsImageSection) &&
+   if (((FileOffset % PAGE_SIZE) == 0) &&
+       ((SegOffset + PAGE_SIZE <= RawLength) || !IsImageSection) &&
        !(MemoryArea->Data.SectionData.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
    {
 
@@ -1140,7 +1106,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
 
       Process = PsGetCurrentProcess();
       PageAddr = MiMapPageInHyperSpace(Process, *Page, &Irql);
-      CacheSegOffset = BaseOffset + CacheSeg->Bcb->CacheSegmentSize - FileOffset;
+      CacheSegOffset = (ULONG_PTR)(BaseOffset + CacheSeg->Bcb->CacheSegmentSize - FileOffset);
       Length = RawLength - SegOffset;
       if (Length <= CacheSegOffset && Length <= PAGE_SIZE)
       {
@@ -1197,7 +1163,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
 NTSTATUS
 NTAPI
 MiReadPage(PMEMORY_AREA MemoryArea,
-           ULONG SegOffset,
+           ULONG_PTR SegOffset,
            PPFN_NUMBER Page)
 /*
  * FUNCTION: Read a page for a section backed memory area.
@@ -1241,7 +1207,6 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
    ULONG_PTR Entry;
    ULONG_PTR Entry1;
    ULONG Attributes;
-   PMM_PAGEOP PageOp;
    PMM_REGION Region;
    BOOLEAN HasSwapEntry;
    PVOID PAddress;
@@ -1279,7 +1244,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
     * Lock the segment
     */
    MmLockSectionSegment(Segment);
-
+   Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
    /*
     * Check if this page needs to be mapped COW
     */
@@ -1294,112 +1259,42 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       Attributes = Region->Protect;
    }
 
-   /*
-    * Get or create a page operation descriptor
-    */
-   PageOp = MmGetPageOp(MemoryArea, NULL, 0, Segment, Offset.LowPart, MM_PAGEOP_PAGEIN, FALSE);
-   if (PageOp == NULL)
-   {
-      DPRINT1("MmGetPageOp failed\n");
-       KeBugCheck(MEMORY_MANAGEMENT);
-   }
-
    /*
     * Check if someone else is already handling this fault, if so wait
     * for them
     */
-   if (PageOp->Thread != PsGetCurrentThread())
+   if (Entry && IS_SWAP_FROM_SSE(Entry) && SWAPENTRY_FROM_SSE(Entry) == MM_WAIT_ENTRY)
    {
       MmUnlockSectionSegment(Segment);
       MmUnlockAddressSpace(AddressSpace);
-      Status = MmspWaitForPageOpCompletionEvent(PageOp);
-      /*
-       * Check for various strange conditions
-       */
-      if (Status != STATUS_SUCCESS)
-      {
-         DPRINT1("Failed to wait for page op, status = %x\n", Status);
-          KeBugCheck(MEMORY_MANAGEMENT);
-      }
-      if (PageOp->Status == STATUS_PENDING)
-      {
-         DPRINT1("Woke for page op before completion\n");
-          KeBugCheck(MEMORY_MANAGEMENT);
-      }
+      MiWaitForPageEvent(NULL, NULL);
       MmLockAddressSpace(AddressSpace);
-      /*
-       * If this wasn't a pagein then restart the operation
-       */
-      if (PageOp->OpType != MM_PAGEOP_PAGEIN)
-      {
-         MmspCompleteAndReleasePageOp(PageOp);
-         DPRINT("Address 0x%.8X\n", Address);
-         return(STATUS_MM_RESTART_OPERATION);
-      }
-
-      /*
-      * If the thread handling this fault has failed then we don't retry
-      */
-      if (!NT_SUCCESS(PageOp->Status))
-      {
-         Status = PageOp->Status;
-         MmspCompleteAndReleasePageOp(PageOp);
-         DPRINT("Address 0x%.8X\n", Address);
-         return(Status);
-      }
-      MmLockSectionSegment(Segment);
-      /*
-       * If the completed fault was for another address space then set the
-       * page in this one.
-       */
-      if (!MmIsPagePresent(Process, Address))
-      {
-         Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
-         HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)PAddress);
-
-         if (PAGE_FROM_SSE(Entry) == 0 || HasSwapEntry)
-         {
-            /*
-             * The page was a private page in another or in our address space
-             */
-            MmUnlockSectionSegment(Segment);
-            MmspCompleteAndReleasePageOp(PageOp);
-            return(STATUS_MM_RESTART_OPERATION);
-         }
-
-         Page = PFN_FROM_SSE(Entry);
-
-         MmSharePageEntrySectionSegment(Segment, &Offset);
-
-         /* FIXME: Should we call MmCreateVirtualMappingUnsafe if
-          * (Section->AllocationAttributes & SEC_PHYSICALMEMORY) is true?
-          */
-         Status = MmCreateVirtualMapping(Process,
-                                         PAddress,
-                                         Attributes,
-                                         &Page,
-                                         1);
-         if (!NT_SUCCESS(Status))
-         {
-            DPRINT1("Unable to create virtual mapping\n");
-            KeBugCheck(MEMORY_MANAGEMENT);
-         }
-         MmInsertRmap(Page, Process, Address);
-      }
-      MmUnlockSectionSegment(Segment);
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
       DPRINT("Address 0x%.8X\n", Address);
-      return(STATUS_SUCCESS);
+      return(STATUS_MM_RESTART_OPERATION);
    }
 
    HasSwapEntry = MmIsPageSwapEntry(Process, Address);
+
    if (HasSwapEntry)
    {
+      SWAPENTRY SwapEntry;
+      /*
+       * Is it a wait entry?
+       */
+      MmGetPageFileMapping(Process, Address, &SwapEntry);
+
+      if (SwapEntry == MM_WAIT_ENTRY)
+      {
+         MmUnlockSectionSegment(Segment);
+         MmUnlockAddressSpace(AddressSpace);
+         MiWaitForPageEvent(NULL, NULL);
+         MmLockAddressSpace(AddressSpace);
+         return STATUS_MM_RESTART_OPERATION;
+      }
+
       /*
        * Must be private page we have swapped out.
        */
-      SWAPENTRY SwapEntry;
 
       /*
        * Sanity check
@@ -1454,8 +1349,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       /*
        * Finish the operation
        */
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
+      MiSetPageEvent(Process, Address);
       DPRINT("Address 0x%.8X\n", Address);
       return(STATUS_SUCCESS);
    }
@@ -1469,7 +1363,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       /*
        * Just map the desired physical page
        */
-      Page = Offset.QuadPart >> PAGE_SHIFT;
+      Page = (PFN_NUMBER)(Offset.QuadPart >> PAGE_SHIFT);
       Status = MmCreateVirtualMappingUnsafe(Process,
                                             PAddress,
                                             Region->Protect,
@@ -1485,8 +1379,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       /*
        * Cleanup and release locks
        */
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
+      MiSetPageEvent(Process, Address);
       DPRINT("Address 0x%.8X\n", Address);
       return(STATUS_SUCCESS);
    }
@@ -1527,8 +1420,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       /*
        * Cleanup and release locks
        */
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
+      MiSetPageEvent(Process, Address);
       DPRINT("Address 0x%.8X\n", Address);
       return(STATUS_SUCCESS);
    }
@@ -1548,11 +1440,13 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       /*
        * Release all our locks and read in the page from disk
        */
+      MmSetPageEntrySectionSegment(Segment, &Offset, MAKE_SWAP_SSE(MM_WAIT_ENTRY));
       MmUnlockSectionSegment(Segment);
       MmUnlockAddressSpace(AddressSpace);
 
       if ((Segment->Flags & MM_PAGEFILE_SEGMENT) ||
-          (Offset.QuadPart >= PAGE_ROUND_UP(Segment->RawLength.QuadPart) && Section->AllocationAttributes & SEC_IMAGE))
+          ((Offset.QuadPart >= (LONGLONG)PAGE_ROUND_UP(Segment->RawLength.QuadPart) &&
+          (Section->AllocationAttributes & SEC_IMAGE))))
       {
          MI_SET_USAGE(MI_USAGE_SECTION);
          if (Process) MI_SET_PROCESS2(Process->ImageFileName);
@@ -1566,7 +1460,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       }
       else
       {
-         Status = MiReadPage(MemoryArea, Offset.QuadPart, &Page);
+         Status = MiReadPage(MemoryArea, (ULONG_PTR)Offset.QuadPart, &Page);
          if (!NT_SUCCESS(Status))
          {
             DPRINT1("MiReadPage failed (Status %x)\n", Status);
@@ -1581,32 +1475,17 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
           * Cleanup and release locks
           */
          MmLockAddressSpace(AddressSpace);
-         PageOp->Status = Status;
-         MmspCompleteAndReleasePageOp(PageOp);
+         MiSetPageEvent(Process, Address);
          DPRINT("Address 0x%.8X\n", Address);
          return(Status);
       }
-      /*
-       * Relock the address space and segment
-       */
-      MmLockAddressSpace(AddressSpace);
-      MmLockSectionSegment(Segment);
-
-      /*
-       * Check the entry. No one should change the status of a page
-       * that has a pending page-in.
-       */
-      Entry1 = MmGetPageEntrySectionSegment(Segment, &Offset);
-      if (Entry != Entry1)
-      {
-         DPRINT1("Someone changed ppte entry while we slept\n");
-         KeBugCheck(MEMORY_MANAGEMENT);
-      }
 
       /*
        * Mark the offset within the section as having valid, in-memory
        * data
        */
+      MmLockAddressSpace(AddressSpace);
+      MmLockSectionSegment(Segment);
       Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
       MmSetPageEntrySectionSegment(Segment, &Offset, Entry);
       MmUnlockSectionSegment(Segment);
@@ -1623,8 +1502,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       }
       MmInsertRmap(Page, Process, Address);
 
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
+      MiSetPageEvent(Process, Address);
       DPRINT("Address 0x%.8X\n", Address);
       return(STATUS_SUCCESS);
    }
@@ -1668,7 +1546,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       Entry1 = MmGetPageEntrySectionSegment(Segment, &Offset);
       if (Entry != Entry1)
       {
-         DPRINT1("Someone changed ppte entry while we slept\n");
+          DPRINT1("Someone changed ppte entry while we slept (%x vs %x)\n", Entry, Entry1);
           KeBugCheck(MEMORY_MANAGEMENT);
       }
 
@@ -1695,8 +1573,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
           KeBugCheck(MEMORY_MANAGEMENT);
       }
       MmInsertRmap(Page, Process, Address);
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
+      MiSetPageEvent(Process, Address);
       DPRINT("Address 0x%.8X\n", Address);
       return(STATUS_SUCCESS);
    }
@@ -1723,8 +1600,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
           KeBugCheck(MEMORY_MANAGEMENT);
       }
       MmInsertRmap(Page, Process, Address);
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
+      MiSetPageEvent(Process, Address);
       DPRINT("Address 0x%.8X\n", Address);
       return(STATUS_SUCCESS);
    }
@@ -1743,10 +1619,10 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
    NTSTATUS Status;
    PVOID PAddress;
    LARGE_INTEGER Offset;
-   PMM_PAGEOP PageOp;
    PMM_REGION Region;
-   ULONG Entry;
+   ULONG_PTR Entry;
    PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
+   SWAPENTRY SwapEntry;
 
    DPRINT("MmAccessFaultSectionView(%x, %x, %x, %x)\n", AddressSpace, MemoryArea, Address);
 
@@ -1800,53 +1676,40 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
       MmSetPageProtect(Process, Address, Region->Protect);
       return(STATUS_SUCCESS);
    }
-   
+
    if(OldPage == 0)
       DPRINT("OldPage == 0!\n");
-   
+
    /*
     * Get or create a pageop
     */
-   PageOp = MmGetPageOp(MemoryArea, NULL, 0, Segment, Offset.LowPart,
-                        MM_PAGEOP_ACCESSFAULT, FALSE);
-   if (PageOp == NULL)
-   {
-      DPRINT1("MmGetPageOp failed\n");
-       KeBugCheck(MEMORY_MANAGEMENT);
-   }
+   MmLockSectionSegment(Segment);
+   Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
 
    /*
     * Wait for any other operations to complete
     */
-   if (PageOp->Thread != PsGetCurrentThread())
+   if (Entry == SWAPENTRY_FROM_SSE(MM_WAIT_ENTRY))
    {
-      MmUnlockAddressSpace(AddressSpace);
-      Status = MmspWaitForPageOpCompletionEvent(PageOp);
-      /*
-      * Check for various strange conditions
-      */
-      if (Status == STATUS_TIMEOUT)
-      {
-         DPRINT1("Failed to wait for page op, status = %x\n", Status);
-          KeBugCheck(MEMORY_MANAGEMENT);
-      }
-      if (PageOp->Status == STATUS_PENDING)
-      {
-         DPRINT1("Woke for page op before completion\n");
-          KeBugCheck(MEMORY_MANAGEMENT);
-      }
-      /*
-      * Restart the operation
-      */
-      MmLockAddressSpace(AddressSpace);
-      MmspCompleteAndReleasePageOp(PageOp);
-      DPRINT("Address 0x%.8X\n", Address);
-      return(STATUS_MM_RESTART_OPERATION);
+       MmUnlockSectionSegment(Segment);
+       MmUnlockAddressSpace(AddressSpace);
+       MiWaitForPageEvent(NULL, NULL);
+       /*
+        * Restart the operation
+        */
+       MmLockAddressSpace(AddressSpace);
+       DPRINT("Address 0x%.8X\n", Address);
+       return(STATUS_MM_RESTART_OPERATION);
    }
 
+   MmDeleteRmap(OldPage, Process, PAddress);
+   MmDeleteVirtualMapping(Process, PAddress, FALSE, NULL, NULL);
+   MmCreatePageFileMapping(Process, PAddress, MM_WAIT_ENTRY);
+
    /*
     * Release locks now we have the pageop
     */
+   MmUnlockSectionSegment(Segment);
    MmUnlockAddressSpace(AddressSpace);
 
    /*
@@ -1864,17 +1727,14 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
    /*
     * Copy the old page
     */
-   MiCopyFromUserPage(NewPage, PAddress);
+   MiCopyFromUserPage(NewPage, OldPage);
 
    MmLockAddressSpace(AddressSpace);
-   /*
-    * Delete the old entry.
-    */
-   MmDeleteVirtualMapping(Process, Address, FALSE, NULL, NULL);
 
    /*
     * Set the PTE to point to the new page
     */
+   MmDeletePageFileMapping(Process, PAddress, &SwapEntry);
    Status = MmCreateVirtualMapping(Process,
                                    PAddress,
                                    Region->Protect,
@@ -1895,14 +1755,13 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
    /*
     * Unshare the old page.
     */
-   MmDeleteRmap(OldPage, Process, PAddress);
+   DPRINT("Swapping page (Old %x New %x)\n", OldPage, NewPage);
    MmInsertRmap(NewPage, Process, PAddress);
    MmLockSectionSegment(Segment);
-   MmUnsharePageEntrySectionSegment(Section, Segment, &Offset, FALSE, FALSE);
+   MmUnsharePageEntrySectionSegment(Section, Segment, &Offset, FALSE, FALSE, NULL);
    MmUnlockSectionSegment(Segment);
 
-   PageOp->Status = STATUS_SUCCESS;
-   MmspCompleteAndReleasePageOp(PageOp);
+   MiSetPageEvent(Process, Address);
    DPRINT("Address 0x%.8X\n", Address);
    return(STATUS_SUCCESS);
 }
@@ -1912,7 +1771,7 @@ MmPageOutDeleteMapping(PVOID Context, PEPROCESS Process, PVOID Address)
 {
    MM_SECTION_PAGEOUT_CONTEXT* PageOutContext;
    BOOLEAN WasDirty;
-   PFN_NUMBER Page;
+   PFN_NUMBER Page = 0;
 
    PageOutContext = (MM_SECTION_PAGEOUT_CONTEXT*)Context;
    if (Process)
@@ -1936,7 +1795,8 @@ MmPageOutDeleteMapping(PVOID Context, PEPROCESS Process, PVOID Address)
                                        PageOutContext->Segment,
                                        &PageOutContext->Offset,
                                        PageOutContext->WasDirty,
-                                       TRUE);
+                                       TRUE,
+                                       &PageOutContext->SectionEntry);
       MmUnlockSectionSegment(PageOutContext->Segment);
    }
    if (Process)
@@ -1948,22 +1808,18 @@ MmPageOutDeleteMapping(PVOID Context, PEPROCESS Process, PVOID Address)
    {
       MmReleasePageMemoryConsumer(MC_USER, Page);
    }
-
-   DPRINT("PhysicalAddress %x, Address %x\n", Page << PAGE_SHIFT, Address);
 }
 
 NTSTATUS
 NTAPI
 MmPageOutSectionView(PMMSUPPORT AddressSpace,
                      MEMORY_AREA* MemoryArea,
-                     PVOID Address,
-                     PMM_PAGEOP PageOp)
+                     PVOID Address, ULONG_PTR Entry)
 {
    PFN_NUMBER Page;
    MM_SECTION_PAGEOUT_CONTEXT Context;
    SWAPENTRY SwapEntry;
-   ULONG Entry;
-   ULONG FileOffset;
+   ULONGLONG FileOffset;
    NTSTATUS Status;
    PFILE_OBJECT FileObject;
 #ifndef NEWCC
@@ -1981,6 +1837,7 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
     */
    Context.Segment = MemoryArea->Data.SectionData.Segment;
    Context.Section = MemoryArea->Data.SectionData.Section;
+   Context.SectionEntry = Entry;
    Context.CallingProcess = Process;
 
    Context.Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
@@ -1992,6 +1849,8 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
    FileObject = Context.Section->FileObject;
    DirectMapped = FALSE;
 
+   MmLockSectionSegment(Context.Segment);
+
 #ifndef NEWCC
    if (FileObject != NULL &&
        !(Context.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))
@@ -2043,16 +1902,14 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
    {
        DPRINT("Cannot page out locked section page: 0x%p (RefCount: %d)\n",
                Page, MmGetReferenceCountPage(Page));
-       PageOp->Status = STATUS_UNSUCCESSFUL;
-       MmspCompleteAndReleasePageOp(PageOp);
+       MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry);
+       MmUnlockSectionSegment(Context.Segment);
        return STATUS_UNSUCCESSFUL;
    }
 
    /*
     * Prepare the context structure for the rmap delete call.
     */
-   MmLockSectionSegment(Context.Segment);
-   Entry = MmGetPageEntrySectionSegment(Context.Segment, &Context.Offset);
    MmUnlockSectionSegment(Context.Segment);
    Context.WasDirty = FALSE;
    if (Context.Segment->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA ||
@@ -2085,9 +1942,12 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
    }
 
    MmDeleteAllRmaps(Page, (PVOID)&Context, MmPageOutDeleteMapping);
-   MmLockSectionSegment(Context.Segment);
-   Entry = MmGetPageEntrySectionSegment(Context.Segment, &Context.Offset);
-   MmUnlockSectionSegment(Context.Segment);
+
+   /* Since we passed in a surrogate, we'll get back the page entry
+    * state in our context.  This is intended to make intermediate
+    * decrements of share count not release the wait entry.
+    */
+   Entry = Context.SectionEntry;
 
    /*
     * If this wasn't a private page then we should have reduced the entry to
@@ -2125,8 +1985,7 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
          MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, MAKE_SWAP_SSE(SwapEntry));
          MmUnlockSectionSegment(Context.Segment);
          MmReleasePageMemoryConsumer(MC_USER, Page);
-         PageOp->Status = STATUS_SUCCESS;
-         MmspCompleteAndReleasePageOp(PageOp);
+         MiSetPageEvent(NULL, NULL);
          return(STATUS_SUCCESS);
       }
    }
@@ -2148,8 +2007,7 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
             MmUnlockSectionSegment(Context.Segment);
          }
          MmReleasePageMemoryConsumer(MC_USER, Page);
-         PageOp->Status = STATUS_SUCCESS;
-         MmspCompleteAndReleasePageOp(PageOp);
+         MiSetPageEvent(NULL, NULL);
          return(STATUS_SUCCESS);
       }
    }
@@ -2162,7 +2020,7 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
          KeBugCheckEx(MEMORY_MANAGEMENT, STATUS_UNSUCCESSFUL, SwapEntry, (ULONG_PTR)Process, (ULONG_PTR)Address);
       }
 #ifndef NEWCC
-      Status = CcRosUnmapCacheSegment(Bcb, FileOffset, FALSE);
+      Status = CcRosUnmapCacheSegment(Bcb, (ULONG)FileOffset, FALSE);
 #else
       Status = STATUS_SUCCESS;
 #endif
@@ -2170,11 +2028,10 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
       if (!NT_SUCCESS(Status))
       {
          DPRINT1("CCRosUnmapCacheSegment failed, status = %x\n", Status);
-         KeBugCheckEx(MEMORY_MANAGEMENT, Status, (ULONG_PTR)Bcb, FileOffset, (ULONG_PTR)Address);
+         KeBugCheckEx(MEMORY_MANAGEMENT, Status, (ULONG_PTR)Bcb, (ULONG_PTR)FileOffset, (ULONG_PTR)Address);
       }
 #endif
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
+      MiSetPageEvent(NULL, NULL);
       return(STATUS_SUCCESS);
    }
    else if (!Context.WasDirty && !DirectMapped && !Context.Private)
@@ -2186,13 +2043,12 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
          KeBugCheckEx(MEMORY_MANAGEMENT, SwapEntry, Page, (ULONG_PTR)Process, (ULONG_PTR)Address);
       }
       MmReleasePageMemoryConsumer(MC_USER, Page);
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
+      MiSetPageEvent(NULL, NULL);
       return(STATUS_SUCCESS);
    }
    else if (!Context.WasDirty && Context.Private && SwapEntry != 0)
    {
-      DPRINT1("Not dirty and private and not swapped (%p:%p)\n", Process, Address);
+      DPRINT("Not dirty and private and not swapped (%p:%p)\n", Process, Address);
       MmSetSavedSwapEntryPage(Page, 0);
       MmLockAddressSpace(AddressSpace);
       Status = MmCreatePageFileMapping(Process,
@@ -2205,8 +2061,7 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
          KeBugCheckEx(MEMORY_MANAGEMENT, Status, (ULONG_PTR)Process, (ULONG_PTR)Address, SwapEntry);
       }
       MmReleasePageMemoryConsumer(MC_USER, Page);
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
+      MiSetPageEvent(NULL, NULL);
       return(STATUS_SUCCESS);
    }
 
@@ -2237,7 +2092,7 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
          }
          else
          {
-            LONG OldEntry;
+            ULONG_PTR OldEntry;
             /*
              * For non-private pages if the page wasn't direct mapped then
              * set it back into the section segment entry so we don't loose
@@ -2252,17 +2107,16 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
             MmInsertRmap(Page,
                          Process,
                          Address);
-           // If we got here, the previous entry should have been a wait
+            // If we got here, the previous entry should have been a wait
             Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
-           MmLockSectionSegment(Context.Segment);
-           OldEntry = MmGetPageEntrySectionSegment(Context.Segment, &Context.Offset);
-           ASSERT(OldEntry == 0 || OldEntry == MAKE_SWAP_SSE(MM_WAIT_ENTRY));
+            MmLockSectionSegment(Context.Segment);
+            OldEntry = MmGetPageEntrySectionSegment(Context.Segment, &Context.Offset);
+            ASSERT(OldEntry == 0 || OldEntry == MAKE_SWAP_SSE(MM_WAIT_ENTRY));
             MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry);
-           MmUnlockSectionSegment(Context.Segment);
+            MmUnlockSectionSegment(Context.Segment);
          }
          MmUnlockAddressSpace(AddressSpace);
-         PageOp->Status = STATUS_UNSUCCESSFUL;
-         MmspCompleteAndReleasePageOp(PageOp);
+         MiSetPageEvent(NULL, NULL);
          return(STATUS_PAGEFILE_QUOTA);
       }
    }
@@ -2307,8 +2161,7 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
          MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry);
       }
       MmUnlockAddressSpace(AddressSpace);
-      PageOp->Status = STATUS_UNSUCCESSFUL;
-      MmspCompleteAndReleasePageOp(PageOp);
+      MiSetPageEvent(NULL, NULL);
       return(STATUS_UNSUCCESSFUL);
    }
 
@@ -2316,12 +2169,13 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
     * Otherwise we have succeeded.
     */
    DPRINT("MM: Wrote section page 0x%.8X to swap!\n", Page << PAGE_SHIFT);
-   MmLockSectionSegment(Context.Segment);
    MmSetSavedSwapEntryPage(Page, 0);
    if (Context.Segment->Flags & MM_PAGEFILE_SEGMENT ||
          Context.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)
    {
+      MmLockSectionSegment(Context.Segment);
       MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, MAKE_SWAP_SSE(SwapEntry));
+      MmUnlockSectionSegment(Context.Segment);
    }
    else
    {
@@ -2331,9 +2185,11 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
    if (Context.Private)
    {
       MmLockAddressSpace(AddressSpace);
+      MmLockSectionSegment(Context.Segment);
       Status = MmCreatePageFileMapping(Process,
                                        Address,
                                        SwapEntry);
+      MmUnlockSectionSegment(Context.Segment);
       MmUnlockAddressSpace(AddressSpace);
       if (!NT_SUCCESS(Status))
       {
@@ -2343,13 +2199,15 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
    }
    else
    {
+      MmLockAddressSpace(AddressSpace);
+      MmLockSectionSegment(Context.Segment);
       Entry = MAKE_SWAP_SSE(SwapEntry);
       MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry);
+      MmUnlockSectionSegment(Context.Segment);
+      MmUnlockAddressSpace(AddressSpace);
    }
 
-   MmUnlockSectionSegment(Context.Segment);
-   PageOp->Status = STATUS_SUCCESS;
-   MmspCompleteAndReleasePageOp(PageOp);
+   MiSetPageEvent(NULL, NULL);
    return(STATUS_SUCCESS);
 }
 
@@ -2358,14 +2216,14 @@ NTAPI
 MmWritePageSectionView(PMMSUPPORT AddressSpace,
                        PMEMORY_AREA MemoryArea,
                        PVOID Address,
-                       PMM_PAGEOP PageOp)
+                       ULONG PageEntry)
 {
    LARGE_INTEGER Offset;
    PROS_SECTION_OBJECT Section;
    PMM_SECTION_SEGMENT Segment;
    PFN_NUMBER Page;
    SWAPENTRY SwapEntry;
-   ULONG Entry;
+   ULONG_PTR Entry;
    BOOLEAN Private;
    NTSTATUS Status;
    PFILE_OBJECT FileObject;
@@ -2455,12 +2313,16 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
     */
    if (DirectMapped && !Private)
    {
+      LARGE_INTEGER SOffset;
       ASSERT(SwapEntry == 0);
+      SOffset.QuadPart = Offset.QuadPart + Segment->Image.FileOffset;
 #ifndef NEWCC
-      CcRosMarkDirtyCacheSegment(Bcb, Offset.LowPart + Segment->Image.FileOffset);
+      CcRosMarkDirtyCacheSegment(Bcb, Offset.LowPart);
 #endif
-      PageOp->Status = STATUS_SUCCESS;
-      MmspCompleteAndReleasePageOp(PageOp);
+      MmLockSectionSegment(Segment);
+      MmSetPageEntrySectionSegment(Segment, &Offset, PageEntry);
+      MmUnlockSectionSegment(Segment);
+      MiSetPageEvent(NULL, NULL);
       return(STATUS_SUCCESS);
    }
 
@@ -2473,8 +2335,7 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
       if (SwapEntry == 0)
       {
          MmSetDirtyAllRmaps(Page);
-         PageOp->Status = STATUS_UNSUCCESSFUL;
-         MmspCompleteAndReleasePageOp(PageOp);
+         MiSetPageEvent(NULL, NULL);
          return(STATUS_PAGEFILE_QUOTA);
       }
       MmSetSavedSwapEntryPage(Page, SwapEntry);
@@ -2489,8 +2350,7 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
       DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
               Status);
       MmSetDirtyAllRmaps(Page);
-      PageOp->Status = STATUS_UNSUCCESSFUL;
-      MmspCompleteAndReleasePageOp(PageOp);
+      MiSetPageEvent(NULL, NULL);
       return(STATUS_UNSUCCESSFUL);
    }
 
@@ -2498,8 +2358,7 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
     * Otherwise we have succeeded.
     */
    DPRINT("MM: Wrote section page 0x%.8X to swap!\n", Page << PAGE_SHIFT);
-   PageOp->Status = STATUS_SUCCESS;
-   MmspCompleteAndReleasePageOp(PageOp);
+   MiSetPageEvent(NULL, NULL);
    return(STATUS_SUCCESS);
 }
 
@@ -2533,9 +2392,18 @@ MmAlterViewAttributes(PMMSUPPORT AddressSpace,
    {
       for (i = 0; i < PAGE_ROUND_UP(RegionSize) / PAGE_SIZE; i++)
       {
+         SWAPENTRY SwapEntry;
          PVOID Address = (char*)BaseAddress + (i * PAGE_SIZE);
          ULONG Protect = NewProtect;
 
+         /* Wait for a wait entry to disappear */
+         do {
+             MmGetPageFileMapping(Process, Address, &SwapEntry);
+             if (SwapEntry != MM_WAIT_ENTRY)
+                 break;
+             MiWaitForPageEvent(Process, Address);
+         } while (TRUE);
+
          /*
           * If we doing COW for this segment then check if the page is
           * already private.
@@ -2543,12 +2411,16 @@ MmAlterViewAttributes(PMMSUPPORT AddressSpace,
          if (DoCOW && MmIsPagePresent(Process, Address))
          {
             LARGE_INTEGER Offset;
-            ULONG Entry;
+            ULONG_PTR Entry;
             PFN_NUMBER Page;
 
             Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
                      + MemoryArea->Data.SectionData.ViewOffset.QuadPart;
             Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
+            /*
+             * An MM_WAIT_ENTRY is ok in this case...  It'll just count as
+             * IS_SWAP_FROM_SSE and we'll do the right thing.
+             */
             Page = MmGetPfnForProcess(Process, Address);
 
             Protect = PAGE_READONLY;
@@ -2655,7 +2527,7 @@ MmpFreePageFileSegment(PMM_SECTION_SEGMENT Segment)
 {
    ULONG Length;
    LARGE_INTEGER Offset;
-   ULONG Entry;
+   ULONG_PTR Entry;
    SWAPENTRY SavedSwapEntry;
    PFN_NUMBER Page;
 
@@ -2739,7 +2611,7 @@ MmpDeleteSection(PVOID ObjectBody)
          ULONG RefCount = 0;
          PMM_SECTION_SEGMENT Segment = Section->Segment;
 
-         if (Segment && 
+         if (Segment &&
                  (RefCount = InterlockedDecrementUL(&Segment->ReferenceCount)) == 0)
          {
                  DPRINT("Freeing section segment\n");
@@ -2855,6 +2727,10 @@ MmInitSectionImplementation(VOID)
 
    DPRINT("Creating Section Object Type\n");
 
+   /* Initialize the section based root */
+   ASSERT(MmSectionBasedRoot.NumberGenericTableElements == 0);
+   MmSectionBasedRoot.BalancedRoot.u1.Parent = &MmSectionBasedRoot.BalancedRoot;
+
    /* Initialize the Section object type  */
    RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
    RtlInitUnicodeString(&Name, L"Section");
@@ -3303,7 +3179,7 @@ ExeFmtpReadFile(IN PVOID File,
 
    Status = MiSimpleRead(FileObject, &FileOffset, Buffer, BufferSize, TRUE, &Iosb);
 
-   UsedSize = Iosb.Information;
+   UsedSize = (ULONG)Iosb.Information;
 
    if(NT_SUCCESS(Status) && UsedSize < OffsetAdjustment)
    {
@@ -3536,7 +3412,7 @@ MmspPageAlignSegments
          PMM_SECTION_SEGMENT Segment = &ImageSectionObject->Segments[i];
          ULONG_PTR EndOfEffectiveSegment;
 
-         EndOfEffectiveSegment = EffectiveSegment->Image.VirtualAddress + EffectiveSegment->Length.QuadPart;
+         EndOfEffectiveSegment = (ULONG_PTR)(EffectiveSegment->Image.VirtualAddress + EffectiveSegment->Length.QuadPart);
          ASSERT((EndOfEffectiveSegment % PAGE_SIZE) == 0);
 
          /*
@@ -4038,13 +3914,11 @@ static VOID
 MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
                   PFN_NUMBER Page, SWAPENTRY SwapEntry, BOOLEAN Dirty)
 {
-   ULONG Entry;
+   ULONG_PTR Entry;
    PFILE_OBJECT FileObject;
    PBCB Bcb;
    LARGE_INTEGER Offset;
    SWAPENTRY SavedSwapEntry;
-   PMM_PAGEOP PageOp;
-   NTSTATUS Status;
    PROS_SECTION_OBJECT Section;
    PMM_SECTION_SEGMENT Segment;
    PMMSUPPORT AddressSpace;
@@ -4061,28 +3935,19 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
    Section = MemoryArea->Data.SectionData.Section;
    Segment = MemoryArea->Data.SectionData.Segment;
 
-   PageOp = MmCheckForPageOp(MemoryArea, NULL, NULL, Segment, Offset.LowPart);
-
-   while (PageOp)
+   Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
+   while (Entry && IS_SWAP_FROM_SSE(Entry) && SWAPENTRY_FROM_SSE(Entry) == MM_WAIT_ENTRY)
    {
       MmUnlockSectionSegment(Segment);
       MmUnlockAddressSpace(AddressSpace);
 
-      Status = MmspWaitForPageOpCompletionEvent(PageOp);
-      if (Status != STATUS_SUCCESS)
-      {
-         DPRINT1("Failed to wait for page op, status = %x\n", Status);
-         KeBugCheck(MEMORY_MANAGEMENT);
-      }
+      MiWaitForPageEvent(NULL, NULL);
 
       MmLockAddressSpace(AddressSpace);
       MmLockSectionSegment(Segment);
-      MmspCompleteAndReleasePageOp(PageOp);
-      PageOp = MmCheckForPageOp(MemoryArea, NULL, NULL, Segment, Offset.LowPart);
+      Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
    }
 
-   Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
-
    /*
     * For a dirty, datafile, non-private page mark it as dirty in the
     * cache manager.
@@ -4094,7 +3959,7 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
          FileObject = MemoryArea->Data.SectionData.Section->FileObject;
          Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
 #ifndef NEWCC
-         CcRosMarkDirtyCacheSegment(Bcb, Offset.QuadPart + Segment->Image.FileOffset);
+         CcRosMarkDirtyCacheSegment(Bcb, (ULONG)(Offset.QuadPart + Segment->Image.FileOffset));
 #endif
          ASSERT(SwapEntry == 0);
       }
@@ -4140,7 +4005,7 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
       else
       {
          MmDeleteRmap(Page, Process, Address);
-         MmUnsharePageEntrySectionSegment(Section, Segment, &Offset, Dirty, FALSE);
+         MmUnsharePageEntrySectionSegment(Section, Segment, &Offset, Dirty, FALSE, NULL);
       }
    }
 }
@@ -4202,20 +4067,17 @@ MmUnmapViewOfSegment(PMMSUPPORT AddressSpace,
    return(Status);
 }
 
-/*
- * @implemented
- */
-NTSTATUS NTAPI
-MmUnmapViewOfSection(PEPROCESS Process,
-                     PVOID BaseAddress)
+NTSTATUS
+NTAPI
+MiRosUnmapViewOfSection(IN PEPROCESS Process,
+                        IN PVOID BaseAddress,
+                        IN ULONG Flags)
 {
    NTSTATUS Status;
    PMEMORY_AREA MemoryArea;
    PMMSUPPORT AddressSpace;
    PROS_SECTION_OBJECT Section;
-   PMM_PAGEOP PageOp;
-   ULONG_PTR Offset;
-    PVOID ImageBaseAddress = 0;
+   PVOID ImageBaseAddress = 0;
 
    DPRINT("Opening memory area Process %x BaseAddress %x\n",
           Process, BaseAddress);
@@ -4231,45 +4093,13 @@ MmUnmapViewOfSection(PEPROCESS Process,
        MemoryArea->Type != MEMORY_AREA_SECTION_VIEW ||
        MemoryArea->DeleteInProgress)
    {
+      ASSERT(MemoryArea->Type != MEMORY_AREA_OWNED_BY_ARM3);
       MmUnlockAddressSpace(AddressSpace);
       return STATUS_NOT_MAPPED_VIEW;
    }
 
    MemoryArea->DeleteInProgress = TRUE;
 
-   while (MemoryArea->PageOpCount)
-   {
-      Offset = PAGE_ROUND_UP((ULONG_PTR)MemoryArea->EndingAddress - (ULONG_PTR)MemoryArea->StartingAddress);
-
-      while (Offset)
-      {
-         Offset -= PAGE_SIZE;
-         PageOp = MmCheckForPageOp(MemoryArea, NULL, NULL,
-                                   MemoryArea->Data.SectionData.Segment,
-                                   Offset + MemoryArea->Data.SectionData.ViewOffset.QuadPart);
-         if (PageOp)
-         {
-            MmUnlockAddressSpace(AddressSpace);
-            Status = MmspWaitForPageOpCompletionEvent(PageOp);
-            if (Status != STATUS_SUCCESS)
-            {
-               DPRINT1("Failed to wait for page op, status = %x\n", Status);
-               KeBugCheck(MEMORY_MANAGEMENT);
-            }
-            MmLockAddressSpace(AddressSpace);
-            MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace,
-                                                     BaseAddress);
-            if (MemoryArea == NULL ||
-                MemoryArea->Type != MEMORY_AREA_SECTION_VIEW)
-            {
-               MmUnlockAddressSpace(AddressSpace);
-               return STATUS_NOT_MAPPED_VIEW;
-            }
-            break;
-         }
-      }
-   }
-
    Section = MemoryArea->Data.SectionData.Section;
 
    if (Section->AllocationAttributes & SEC_IMAGE)
@@ -4538,7 +4368,7 @@ MmMapViewOfSection(IN PVOID SectionObject,
 
    if (MiIsRosSectionObject(SectionObject) == FALSE)
    {
-       DPRINT1("Mapping ARM3 section into %s\n", Process->ImageFileName);
+       DPRINT("Mapping ARM3 section into %s\n", Process->ImageFileName);
        return MmMapViewOfArm3Section(SectionObject,
                                      Process,
                                      BaseAddress,
@@ -4592,8 +4422,8 @@ MmMapViewOfSection(IN PVOID SectionObject,
          if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD))
          {
             ULONG_PTR MaxExtent;
-            MaxExtent = (ULONG_PTR)SectionSegments[i].Image.VirtualAddress +
-                        SectionSegments[i].Length.QuadPart;
+            MaxExtent = (ULONG_PTR)(SectionSegments[i].Image.VirtualAddress +
+                        SectionSegments[i].Length.QuadPart);
             ImageSize = max(ImageSize, MaxExtent);
          }
       }
@@ -4875,7 +4705,6 @@ MmMapViewInSystemSpace (IN PVOID SectionObject,
 
     if (MiIsRosSectionObject(SectionObject) == FALSE)
     {
-        DPRINT1("ARM3 System Mapping\n");
         return MiMapViewInSystemSpace(SectionObject,
                                       &MmSession,
                                       MappedBase,
@@ -4917,11 +4746,9 @@ MmMapViewInSystemSpace (IN PVOID SectionObject,
    return Status;
 }
 
-/*
- * @implemented
- */
-NTSTATUS NTAPI
-MmUnmapViewInSystemSpace (IN PVOID MappedBase)
+NTSTATUS
+NTAPI
+MiRosUnmapViewInSystemSpace(IN PVOID MappedBase)
 {
    PMMSUPPORT AddressSpace;
    NTSTATUS Status;
@@ -4939,7 +4766,6 @@ MmUnmapViewInSystemSpace (IN PVOID MappedBase)
    return Status;
 }
 
-
 /**********************************************************************
  * NAME       EXPORTED
  *  MmCreateSection@
@@ -5046,7 +4872,7 @@ MmCreateSection (OUT PVOID  * Section,
         DPRINT("Creating a section with WRITE access\n");
         FileAccess = FILE_READ_DATA | FILE_WRITE_DATA | SYNCHRONIZE;
     }
-    else 
+    else
     {
         DPRINT("Creating a section with READ access\n");
         FileAccess = FILE_READ_DATA | SYNCHRONIZE;