[CMAKE]
[reactos.git] / ntoskrnl / mm / rmap.c
index 3180e0e..8d6867e 100644 (file)
@@ -10,6 +10,9 @@
 /* INCLUDES *****************************************************************/
 
 #include <ntoskrnl.h>
+#ifdef NEWCC
+#include "../cache/section/newmm.h"
+#endif
 #define NDEBUG
 #include <debug.h>
 
 
 /* TYPES ********************************************************************/
 
-typedef struct _MM_RMAP_ENTRY
-{
-   struct _MM_RMAP_ENTRY* Next;
-   PEPROCESS Process;
-   PVOID Address;
-#if DBG
-   PVOID Caller;
-#endif
-}
-MM_RMAP_ENTRY, *PMM_RMAP_ENTRY;
-
 /* GLOBALS ******************************************************************/
 
-static FAST_MUTEX RmapListLock;
 static NPAGED_LOOKASIDE_LIST RmapLookasideList;
+FAST_MUTEX RmapListLock;
 
 /* FUNCTIONS ****************************************************************/
 
@@ -54,7 +46,7 @@ MmInitializeRmapList(VOID)
 
 NTSTATUS
 NTAPI
-MmWritePagePhysicalAddress(PFN_TYPE Page)
+MmPageOutPhysicalAddress(PFN_NUMBER Page)
 {
    PMM_RMAP_ENTRY entry;
    PMEMORY_AREA MemoryArea;
@@ -66,10 +58,6 @@ MmWritePagePhysicalAddress(PFN_TYPE Page)
    ULONG Offset;
    NTSTATUS Status = STATUS_SUCCESS;
 
-   /*
-    * Check that the address still has a valid rmap; then reference the
-    * process so it isn't freed while we are working.
-    */
    ExAcquireFastMutex(&RmapListLock);
    entry = MmGetRmapListHeadPage(Page);
    if (entry == NULL)
@@ -78,137 +66,9 @@ MmWritePagePhysicalAddress(PFN_TYPE Page)
       return(STATUS_UNSUCCESSFUL);
    }
    Process = entry->Process;
-   Address = entry->Address;
-   if ((((ULONG_PTR)Address) & 0xFFF) != 0)
-   {
-      KeBugCheck(MEMORY_MANAGEMENT);
-   }
-   if (Address < MmSystemRangeStart)
-   {
-      Status = ObReferenceObjectByPointer(Process, PROCESS_ALL_ACCESS, NULL, KernelMode);
-      ExReleaseFastMutex(&RmapListLock);
-      if (!NT_SUCCESS(Status))
-      {
-         return Status;
-      }
-      AddressSpace = &Process->Vm;
-   }
-   else
-   {
-      ExReleaseFastMutex(&RmapListLock);
-      AddressSpace = MmGetKernelAddressSpace();
-   }
-
-   /*
-    * Lock the address space; then check that the address we are using
-    * still corresponds to a valid memory area (the page might have been
-    * freed or paged out after we read the rmap entry.)
-    */
-   MmLockAddressSpace(AddressSpace);
-   MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address);
-   if (MemoryArea == NULL || MemoryArea->DeleteInProgress)
-   {
-      MmUnlockAddressSpace(AddressSpace);
-      if (Address < MmSystemRangeStart)
-      {
-         ObDereferenceObject(Process);
-      }
-      return(STATUS_UNSUCCESSFUL);
-   }
-
-   Type = MemoryArea->Type;
-   if (Type == MEMORY_AREA_SECTION_VIEW)
-   {
-      Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
-               + MemoryArea->Data.SectionData.ViewOffset;
-      /*
-       * Get or create a pageop
-       */
-      PageOp = MmGetPageOp(MemoryArea, NULL, 0,
-                           MemoryArea->Data.SectionData.Segment,
-                           Offset, MM_PAGEOP_PAGEOUT, TRUE);
-
-      if (PageOp == NULL)
-      {
-         MmUnlockAddressSpace(AddressSpace);
-         if (Address < MmSystemRangeStart)
-         {
-            ObDereferenceObject(Process);
-         }
-         return(STATUS_UNSUCCESSFUL);
-      }
-
-      /*
-       * Release locks now we have a page op.
-       */
-      MmUnlockAddressSpace(AddressSpace);
-
-      /*
-       * Do the actual page out work.
-       */
-      Status = MmWritePageSectionView(AddressSpace, MemoryArea,
-                                      Address, PageOp);
-   }
-   else if ((Type == MEMORY_AREA_VIRTUAL_MEMORY) || (Type == MEMORY_AREA_PEB_OR_TEB))
-   {
-      PageOp = MmGetPageOp(MemoryArea, Address < MmSystemRangeStart ? Process->UniqueProcessId : NULL,
-                           Address, NULL, 0, MM_PAGEOP_PAGEOUT, TRUE);
 
-      if (PageOp == NULL)
-      {
-         MmUnlockAddressSpace(AddressSpace);
-         if (Address < MmSystemRangeStart)
-         {
-            ObDereferenceObject(Process);
-         }
-         return(STATUS_UNSUCCESSFUL);
-      }
-
-      /*
-       * Release locks now we have a page op.
-       */
-      MmUnlockAddressSpace(AddressSpace);
-
-      /*
-       * Do the actual page out work.
-       */
-      Status = MmWritePageVirtualMemory(AddressSpace, MemoryArea,
-                                        Address, PageOp);
-   }
-   else
-   {
-      KeBugCheck(MEMORY_MANAGEMENT);
-   }
-   if (Address < MmSystemRangeStart)
-   {
-      ObDereferenceObject(Process);
-   }
-   return(Status);
-}
-
-NTSTATUS
-NTAPI
-MmPageOutPhysicalAddress(PFN_TYPE Page)
-{
-   PMM_RMAP_ENTRY entry;
-   PMEMORY_AREA MemoryArea;
-   PMMSUPPORT AddressSpace;
-   ULONG Type;
-   PVOID Address;
-   PEPROCESS Process;
-   PMM_PAGEOP PageOp;
-   ULONG Offset;
-   NTSTATUS Status = STATUS_SUCCESS;
-
-   ExAcquireFastMutex(&RmapListLock);
-   entry = MmGetRmapListHeadPage(Page);
-   if (entry == NULL)
-   {
-      ExReleaseFastMutex(&RmapListLock);
-      return(STATUS_UNSUCCESSFUL);
-   }
-   Process = entry->Process;
    Address = entry->Address;
+
    if ((((ULONG_PTR)Address) & 0xFFF) != 0)
    {
       KeBugCheck(MEMORY_MANAGEMENT);
@@ -216,10 +76,17 @@ MmPageOutPhysicalAddress(PFN_TYPE Page)
 
    if (Address < MmSystemRangeStart)
    {
+       if (!ExAcquireRundownProtection(&Process->RundownProtect))
+       {
+          ExReleaseFastMutex(&RmapListLock);
+          return STATUS_PROCESS_IS_TERMINATING;
+       }
+
       Status = ObReferenceObjectByPointer(Process, PROCESS_ALL_ACCESS, NULL, KernelMode);
       ExReleaseFastMutex(&RmapListLock);
       if (!NT_SUCCESS(Status))
       {
+         ExReleaseRundownProtection(&Process->RundownProtect);
          return Status;
       }
       AddressSpace = &Process->Vm;
@@ -237,6 +104,7 @@ MmPageOutPhysicalAddress(PFN_TYPE Page)
       MmUnlockAddressSpace(AddressSpace);
       if (Address < MmSystemRangeStart)
       {
+         ExReleaseRundownProtection(&Process->RundownProtect);
          ObDereferenceObject(Process);
       }
       return(STATUS_UNSUCCESSFUL);
@@ -258,6 +126,7 @@ MmPageOutPhysicalAddress(PFN_TYPE Page)
          MmUnlockAddressSpace(AddressSpace);
          if (Address < MmSystemRangeStart)
          {
+            ExReleaseRundownProtection(&Process->RundownProtect);
             ObDereferenceObject(Process);
          }
          return(STATUS_UNSUCCESSFUL);
@@ -274,7 +143,7 @@ MmPageOutPhysicalAddress(PFN_TYPE Page)
       Status = MmPageOutSectionView(AddressSpace, MemoryArea,
                                     Address, PageOp);
    }
-   else if ((Type == MEMORY_AREA_VIRTUAL_MEMORY) || (Type == MEMORY_AREA_PEB_OR_TEB))
+   else if (Type == MEMORY_AREA_VIRTUAL_MEMORY)
    {
       PageOp = MmGetPageOp(MemoryArea, Address < MmSystemRangeStart ? Process->UniqueProcessId : NULL,
                            Address, NULL, 0, MM_PAGEOP_PAGEOUT, TRUE);
@@ -283,6 +152,7 @@ MmPageOutPhysicalAddress(PFN_TYPE Page)
          MmUnlockAddressSpace(AddressSpace);
          if (Address < MmSystemRangeStart)
          {
+            ExReleaseRundownProtection(&Process->RundownProtect);
             ObDereferenceObject(Process);
          }
          return(STATUS_UNSUCCESSFUL);
@@ -303,8 +173,10 @@ MmPageOutPhysicalAddress(PFN_TYPE Page)
    {
       KeBugCheck(MEMORY_MANAGEMENT);
    }
+
    if (Address < MmSystemRangeStart)
    {
+      ExReleaseRundownProtection(&Process->RundownProtect);
       ObDereferenceObject(Process);
    }
    return(Status);
@@ -312,7 +184,7 @@ MmPageOutPhysicalAddress(PFN_TYPE Page)
 
 VOID
 NTAPI
-MmSetCleanAllRmaps(PFN_TYPE Page)
+MmSetCleanAllRmaps(PFN_NUMBER Page)
 {
    PMM_RMAP_ENTRY current_entry;
 
@@ -325,15 +197,18 @@ MmSetCleanAllRmaps(PFN_TYPE Page)
    }
    while (current_entry != NULL)
    {
-      MmSetCleanPage(current_entry->Process, current_entry->Address);
-      current_entry = current_entry->Next;
+#ifdef NEWCC
+         if (!RMAP_IS_SEGMENT(current_entry->Address))
+#endif
+                 MmSetCleanPage(current_entry->Process, current_entry->Address);
+         current_entry = current_entry->Next;
    }
    ExReleaseFastMutex(&RmapListLock);
 }
 
 VOID
 NTAPI
-MmSetDirtyAllRmaps(PFN_TYPE Page)
+MmSetDirtyAllRmaps(PFN_NUMBER Page)
 {
    PMM_RMAP_ENTRY current_entry;
 
@@ -346,7 +221,10 @@ MmSetDirtyAllRmaps(PFN_TYPE Page)
    }
    while (current_entry != NULL)
    {
-      MmSetDirtyPage(current_entry->Process, current_entry->Address);
+#ifdef NEWCC
+         if (!RMAP_IS_SEGMENT(current_entry->Address))
+#endif
+                 MmSetDirtyPage(current_entry->Process, current_entry->Address);
       current_entry = current_entry->Next;
    }
    ExReleaseFastMutex(&RmapListLock);
@@ -354,7 +232,7 @@ MmSetDirtyAllRmaps(PFN_TYPE Page)
 
 BOOLEAN
 NTAPI
-MmIsDirtyPageRmap(PFN_TYPE Page)
+MmIsDirtyPageRmap(PFN_NUMBER Page)
 {
    PMM_RMAP_ENTRY current_entry;
 
@@ -367,7 +245,11 @@ MmIsDirtyPageRmap(PFN_TYPE Page)
    }
    while (current_entry != NULL)
    {
-      if (MmIsDirtyPage(current_entry->Process, current_entry->Address))
+         if (
+#ifdef NEWCC
+             !RMAP_IS_SEGMENT(current_entry->Address) && 
+#endif
+                 MmIsDirtyPage(current_entry->Process, current_entry->Address))
       {
          ExReleaseFastMutex(&RmapListLock);
          return(TRUE);
@@ -380,14 +262,16 @@ MmIsDirtyPageRmap(PFN_TYPE Page)
 
 VOID
 NTAPI
-MmInsertRmap(PFN_TYPE Page, PEPROCESS Process,
+MmInsertRmap(PFN_NUMBER Page, PEPROCESS Process,
              PVOID Address)
 {
    PMM_RMAP_ENTRY current_entry;
    PMM_RMAP_ENTRY new_entry;
    ULONG PrevSize;
-
-   Address = (PVOID)PAGE_ROUND_DOWN(Address);
+#ifdef NEWCC
+   if (!RMAP_IS_SEGMENT(Address))
+#endif
+          Address = (PVOID)PAGE_ROUND_DOWN(Address);
 
    new_entry = ExAllocateFromNPagedLookasideList(&RmapLookasideList);
    if (new_entry == NULL)
@@ -404,7 +288,11 @@ MmInsertRmap(PFN_TYPE Page, PEPROCESS Process,
 #endif
 #endif
 
-   if (MmGetPfnForProcess(Process, Address) != Page)
+   if (
+#ifdef NEWCC
+       !RMAP_IS_SEGMENT(Address) && 
+#endif
+          MmGetPfnForProcess(Process, Address) != Page)
    {
       DPRINT1("Insert rmap (%d, 0x%.8X) 0x%.8X which doesn't match physical "
               "address 0x%.8X\n", Process->UniqueProcessId, Address,
@@ -434,23 +322,28 @@ MmInsertRmap(PFN_TYPE Page, PEPROCESS Process,
 #endif
    MmSetRmapListHeadPage(Page, new_entry);
    ExReleaseFastMutex(&RmapListLock);
-   if (Process == NULL)
-   {
-      Process = PsInitialSystemProcess;
-   }
-   if (Process)
+#ifdef NEWCC
+   if (!RMAP_IS_SEGMENT(Address)) 
+#endif
    {
-      PrevSize = InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, PAGE_SIZE);
-      if (PrevSize >= Process->Vm.PeakWorkingSetSize)
-      {
-         Process->Vm.PeakWorkingSetSize = PrevSize + PAGE_SIZE;
-      }
+          if (Process == NULL)
+          {
+                  Process = PsInitialSystemProcess;
+          }
+          if (Process)
+          {
+                  PrevSize = InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, PAGE_SIZE);
+                  if (PrevSize >= Process->Vm.PeakWorkingSetSize)
+                  {
+                          Process->Vm.PeakWorkingSetSize = PrevSize + PAGE_SIZE;
+                  }
+          }
    }
 }
 
 VOID
 NTAPI
-MmDeleteAllRmaps(PFN_TYPE Page, PVOID Context,
+MmDeleteAllRmaps(PFN_NUMBER Page, PVOID Context,
                  VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process,
                                        PVOID Address))
 {
@@ -471,27 +364,38 @@ MmDeleteAllRmaps(PFN_TYPE Page, PVOID Context,
    {
       previous_entry = current_entry;
       current_entry = current_entry->Next;
-      if (DeleteMapping)
-      {
-         DeleteMapping(Context, previous_entry->Process,
-                       previous_entry->Address);
-      }
-      Process = previous_entry->Process;
-      ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry);
-      if (Process == NULL)
-      {
-         Process = PsInitialSystemProcess;
-      }
-      if (Process)
-      {
-         (void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE);
-      }
+#ifdef NEWCC
+         if (!RMAP_IS_SEGMENT(current_entry->Address)) 
+#endif
+         {
+                 if (DeleteMapping)
+                 {
+                         DeleteMapping(Context, previous_entry->Process,
+                                                       previous_entry->Address);
+                 }
+                 Process = previous_entry->Process;
+                 ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry);
+                 if (Process == NULL)
+                 {
+                         Process = PsInitialSystemProcess;
+                 }
+                 if (Process)
+                 {
+                         (void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE);
+                 }
+         } 
+#ifdef NEWCC
+         else 
+         {
+                 ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry);
+         }
+#endif
    }
 }
 
 VOID
 NTAPI
-MmDeleteRmap(PFN_TYPE Page, PEPROCESS Process,
+MmDeleteRmap(PFN_NUMBER Page, PEPROCESS Process,
              PVOID Address)
 {
    PMM_RMAP_ENTRY current_entry, previous_entry;
@@ -499,6 +403,7 @@ MmDeleteRmap(PFN_TYPE Page, PEPROCESS Process,
    ExAcquireFastMutex(&RmapListLock);
    previous_entry = NULL;
    current_entry = MmGetRmapListHeadPage(Page);
+
    while (current_entry != NULL)
    {
       if (current_entry->Process == (PEPROCESS)Process &&
@@ -514,14 +419,19 @@ MmDeleteRmap(PFN_TYPE Page, PEPROCESS Process,
          }
          ExReleaseFastMutex(&RmapListLock);
          ExFreeToNPagedLookasideList(&RmapLookasideList, current_entry);
-        if (Process == NULL)
-        {
-           Process = PsInitialSystemProcess;
-        }
-        if (Process)
-        {
-            (void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE);
-        }
+#ifdef NEWCC
+                if (!RMAP_IS_SEGMENT(Address))
+#endif
+                {
+                        if (Process == NULL)
+                        {
+                                Process = PsInitialSystemProcess;
+                        }
+                        if (Process)
+                        {
+                                (void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE);
+                        }
+                }
          return;
       }
       previous_entry = current_entry;
@@ -529,3 +439,63 @@ MmDeleteRmap(PFN_TYPE Page, PEPROCESS Process,
    }
    KeBugCheck(MEMORY_MANAGEMENT);
 }
+
+#ifdef NEWCC
+PVOID
+NTAPI
+MmGetSegmentRmap(PFN_NUMBER Page, PULONG RawOffset)
+{
+   PCACHE_SECTION_PAGE_TABLE Result = NULL;
+   PMM_RMAP_ENTRY current_entry, previous_entry;
+
+   ExAcquireFastMutex(&RmapListLock);
+   previous_entry = NULL;
+   current_entry = MmGetRmapListHeadPage(Page);
+   while (current_entry != NULL)
+   {
+         if (RMAP_IS_SEGMENT(current_entry->Address))
+      {
+                Result = (PCACHE_SECTION_PAGE_TABLE)current_entry->Process;
+                *RawOffset = (ULONG_PTR)current_entry->Address & ~RMAP_SEGMENT_MASK;
+                InterlockedIncrementUL(&Result->Segment->ReferenceCount);
+         ExReleaseFastMutex(&RmapListLock);
+                return Result;
+      }
+      previous_entry = current_entry;
+      current_entry = current_entry->Next;
+   }
+   ExReleaseFastMutex(&RmapListLock);
+   return NULL;
+}
+
+VOID
+NTAPI
+MmDeleteSectionAssociation(PFN_NUMBER Page)
+{
+   PMM_RMAP_ENTRY current_entry, previous_entry;
+
+   ExAcquireFastMutex(&RmapListLock);
+   previous_entry = NULL;
+   current_entry = MmGetRmapListHeadPage(Page);
+   while (current_entry != NULL)
+   {
+         if (RMAP_IS_SEGMENT(current_entry->Address))
+      {
+         if (previous_entry == NULL)
+         {
+            MmSetRmapListHeadPage(Page, current_entry->Next);
+         }
+         else
+         {
+            previous_entry->Next = current_entry->Next;
+         }
+         ExReleaseFastMutex(&RmapListLock);
+         ExFreeToNPagedLookasideList(&RmapLookasideList, current_entry);
+         return;
+      }
+      previous_entry = current_entry;
+      current_entry = current_entry->Next;
+   }
+   ExReleaseFastMutex(&RmapListLock);
+}
+#endif