Author: jgardou
Date: Tue Nov 15 23:50:04 2011
New Revision: 54392

URL: http://svn.reactos.org/svn/reactos?rev=54392&view=rev
Log:
[NTOSKRNL/MM]
- Some more cleanup.
- Work with page rounded down addresses in SectionView page faults.
- You should not create a virtual mapping on a non page-aligned address range : 
ASSERT about that.
- Flush Tlb each time we change it
- Fix logic I broke in MmCreateVirtualMapping (thanks to Thomas Faber)

Modified:
    trunk/reactos/ntoskrnl/mm/i386/page.c
    trunk/reactos/ntoskrnl/mm/section.c

Modified: trunk/reactos/ntoskrnl/mm/i386/page.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/i386/page.c?rev=54392&r1=54391&r2=54392&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/mm/i386/page.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/i386/page.c [iso-8859-1] Tue Nov 15 23:50:04 2011
@@ -284,37 +284,34 @@
     PageDir = (PULONG)MiAddressToPde(Address);
     if (0 == InterlockedCompareExchangePte(PageDir, 0, 0))
     {
-        if (Address >= MmSystemRangeStart)
-        {
-            if (0 == 
InterlockedCompareExchangePte(&MmGlobalKernelPageDirectory[PdeOffset], 0, 0))
-            {
-                if (Create == FALSE)
-                {
-                    return NULL;
-                }
-                MI_SET_USAGE(MI_USAGE_LEGACY_PAGE_DIRECTORY);
-                if (Process) MI_SET_PROCESS2(Process->ImageFileName);
-                if (!Process) MI_SET_PROCESS2("Kernel Legacy");
-                Status = MmRequestPageMemoryConsumer(MC_SYSTEM, FALSE, &Pfn);
-                if (!NT_SUCCESS(Status) || Pfn == 0)
-                {
-                    KeBugCheck(MEMORY_MANAGEMENT);
-                }
-                Entry = PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE;
-                if(0 != 
InterlockedCompareExchangePte(&MmGlobalKernelPageDirectory[PdeOffset], Entry, 
0))
-                {
-                    MmReleasePageMemoryConsumer(MC_SYSTEM, Pfn);
-                }
-                InterlockedExchangePte(PageDir, 
MmGlobalKernelPageDirectory[PdeOffset]);
-                RtlZeroMemory(MiPteToAddress(PageDir), PAGE_SIZE);
-                return (PULONG)MiAddressToPte(Address);
+        if (0 == 
InterlockedCompareExchangePte(&MmGlobalKernelPageDirectory[PdeOffset], 0, 0))
+        {
+            if (Create == FALSE)
+            {
+                return NULL;
+            }
+            MI_SET_USAGE(MI_USAGE_LEGACY_PAGE_DIRECTORY);
+            if (Process) MI_SET_PROCESS2(Process->ImageFileName);
+            if (!Process) MI_SET_PROCESS2("Kernel Legacy");
+            Status = MmRequestPageMemoryConsumer(MC_SYSTEM, FALSE, &Pfn);
+            if (!NT_SUCCESS(Status) || Pfn == 0)
+            {
+                KeBugCheck(MEMORY_MANAGEMENT);
+            }
+            Entry = PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE;
+            if(0 != 
InterlockedCompareExchangePte(&MmGlobalKernelPageDirectory[PdeOffset], Entry, 
0))
+            {
+                MmReleasePageMemoryConsumer(MC_SYSTEM, Pfn);
             }
             InterlockedExchangePte(PageDir, 
MmGlobalKernelPageDirectory[PdeOffset]);
-        }
-        else
-        {
-            
-        }
+            /* Flush it before accessing it */
+            KeInvalidateTlbEntry(MiPteToAddress(PageDir));
+            RtlZeroMemory(MiPteToAddress(PageDir), PAGE_SIZE);
+            return (PULONG)MiAddressToPte(Address);
+        }
+        InterlockedExchangePte(PageDir, 
MmGlobalKernelPageDirectory[PdeOffset]);
+        /* Flush it before accessing it */
+        KeInvalidateTlbEntry(MiPteToAddress(PageDir));
     }
     return (PULONG)MiAddressToPte(Address);
 }
@@ -700,15 +697,8 @@
     }
     Pte = *Pt;
     InterlockedExchangePte(Pt, SwapEntry << 1);
-    if (Pte != 0)
-    {
-        MiFlushTlb(Pt, Address);
-    }
-    else
-    {
-        MmUnmapPageTable(Pt);
-    }
-    
+    MiFlushTlb(Pt, Address);
+        
     return(STATUS_SUCCESS);
 }
 
@@ -729,6 +719,8 @@
     ULONG Pte;
     DPRINT("MmCreateVirtualMappingUnsafe(%x, %x, %x, %x (%x), %d)\n",
            Process, Address, flProtect, Pages, *Pages, PageCount);
+           
+    ASSERT(((ULONG_PTR)Address % PAGE_SIZE) == 0);
     
     if (Process == NULL)
     {
@@ -772,6 +764,8 @@
     }
     
     Addr = Address;
+    /* MmGetPageTableForProcess should be called on the first run, so
+     * let this trigger it */
     oldPdeOffset = ADDR_TO_PDE_OFFSET(Addr) + 1;
     for (i = 0; i < PageCount; i++, Addr = (PVOID)((ULONG_PTR)Addr + 
PAGE_SIZE))
     {
@@ -785,6 +779,7 @@
         PdeOffset = ADDR_TO_PDE_OFFSET(Addr);
         if (oldPdeOffset != PdeOffset)
         {
+            if(Pt) MmUnmapPageTable(Pt);
             Pt = MmGetPageTableForProcess(Process, Addr, TRUE);
             if (Pt == NULL)
             {
@@ -805,8 +800,18 @@
             KeBugCheck(MEMORY_MANAGEMENT);
         }
         InterlockedExchangePte(Pt, PFN_TO_PTE(Pages[i]) | Attributes);
-        MiFlushTlb(Pt, Addr);
-    }
+        /* flush if currently mapped, just continue editing if hyperspace
+         * NOTE : Do not call MiFlushTlb, as it will unmap the page table,
+         * and we might need it afterwards */
+        if (Address > MmSystemRangeStart ||
+            (Pt >= (PULONG)PAGETABLE_MAP && Pt < (PULONG)PAGETABLE_MAP + 
1024*1024))
+        {
+            KeInvalidateTlbEntry(Addr);
+        }
+    }
+    
+    ASSERT(Addr > Address);
+    MmUnmapPageTable(Pt);
     
     return(STATUS_SUCCESS);
 }

Modified: trunk/reactos/ntoskrnl/mm/section.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/section.c?rev=54392&r1=54391&r2=54392&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/mm/section.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/section.c [iso-8859-1] Tue Nov 15 23:50:04 2011
@@ -1314,7 +1314,6 @@
    ULONG Offset;
    PFN_NUMBER Page;
    NTSTATUS Status;
-   PVOID PAddress;
    PROS_SECTION_OBJECT Section;
    PMM_SECTION_SEGMENT Segment;
    ULONG_PTR Entry;
@@ -1343,8 +1342,8 @@
       return(STATUS_UNSUCCESSFUL);
    }
 
-   PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
-   Offset = (ULONG)((ULONG_PTR)PAddress - 
(ULONG_PTR)MemoryArea->StartingAddress
+   Address = MM_ROUND_DOWN(Address, PAGE_SIZE);
+   Offset = (ULONG)((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
             + MemoryArea->Data.SectionData.ViewOffset);
 
    Segment = MemoryArea->Data.SectionData.Segment;
@@ -1432,7 +1431,7 @@
       if (!MmIsPagePresent(Process, Address))
       {
          Entry = MmGetPageEntrySectionSegment(Segment, Offset);
-         HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)PAddress);
+         HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)Address);
 
          if (PAGE_FROM_SSE(Entry) == 0 || HasSwapEntry)
          {
@@ -1461,7 +1460,7 @@
             DPRINT1("Unable to create virtual mapping\n");
             KeBugCheck(MEMORY_MANAGEMENT);
          }
-         MmInsertRmap(Page, Process, (PVOID)PAddress);
+         MmInsertRmap(Page, Process, Address);
       }
       MmUnlockSectionSegment(Segment);
       PageOp->Status = STATUS_SUCCESS;
@@ -1470,7 +1469,7 @@
       return(STATUS_SUCCESS);
    }
 
-   HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)PAddress);
+   HasSwapEntry = MmIsPageSwapEntry(Process, Address);
    if (HasSwapEntry)
    {
       /*
@@ -1488,7 +1487,7 @@
       }
 
       MmUnlockSectionSegment(Segment);
-      MmDeletePageFileMapping(Process, (PVOID)PAddress, &SwapEntry);
+      MmDeletePageFileMapping(Process, Address, &SwapEntry);
 
       MmUnlockAddressSpace(AddressSpace);
       MI_SET_USAGE(MI_USAGE_SECTION);
@@ -1527,8 +1526,7 @@
       /*
        * Add the page to the process's working set
        */
-      MmInsertRmap(Page, Process, (PVOID)PAddress);
-
+      MmInsertRmap(Page, Process, Address);
       /*
        * Finish the operation
        */
@@ -1600,7 +1598,7 @@
           KeBugCheck(MEMORY_MANAGEMENT);
          return(Status);
       }
-      MmInsertRmap(Page, Process, (PVOID)PAddress);
+      MmInsertRmap(Page, Process, Address);
 
       /*
        * Cleanup and release locks
@@ -1699,7 +1697,7 @@
          DPRINT1("Unable to create virtual mapping\n");
           KeBugCheck(MEMORY_MANAGEMENT);
       }
-      MmInsertRmap(Page, Process, (PVOID)PAddress);
+      MmInsertRmap(Page, Process, Address);
 
       PageOp->Status = STATUS_SUCCESS;
       MmspCompleteAndReleasePageOp(PageOp);
@@ -1772,7 +1770,7 @@
          DPRINT1("Unable to create virtual mapping\n");
           KeBugCheck(MEMORY_MANAGEMENT);
       }
-      MmInsertRmap(Page, Process, (PVOID)PAddress);
+      MmInsertRmap(Page, Process, Address);
       PageOp->Status = STATUS_SUCCESS;
       MmspCompleteAndReleasePageOp(PageOp);
       DPRINT("Address 0x%.8X\n", Address);
@@ -1800,7 +1798,7 @@
          DPRINT1("Unable to create virtual mapping\n");
           KeBugCheck(MEMORY_MANAGEMENT);
       }
-      MmInsertRmap(Page, Process, (PVOID)PAddress);
+      MmInsertRmap(Page, Process, Address);
       PageOp->Status = STATUS_SUCCESS;
       MmspCompleteAndReleasePageOp(PageOp);
       DPRINT("Address 0x%.8X\n", Address);
@@ -1819,7 +1817,6 @@
    PFN_NUMBER OldPage;
    PFN_NUMBER NewPage;
    NTSTATUS Status;
-   PVOID PAddress;
    ULONG Offset;
    PMM_PAGEOP PageOp;
    PMM_REGION Region;
@@ -1840,8 +1837,8 @@
    /*
     * Find the offset of the page
     */
-   PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
-   Offset = (ULONG)((ULONG_PTR)PAddress - 
(ULONG_PTR)MemoryArea->StartingAddress
+   Address = MM_ROUND_DOWN(Address, PAGE_SIZE);
+   Offset = (ULONG)((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
             + MemoryArea->Data.SectionData.ViewOffset);
 
    Segment = MemoryArea->Data.SectionData.Segment;
@@ -1874,7 +1871,7 @@
        PFN_FROM_SSE(Entry) != OldPage)
    {
       /* This is a private page. We must only change the page protection. */
-      MmSetPageProtect(Process, PAddress, Region->Protect);
+      MmSetPageProtect(Process, Address, Region->Protect);
       return(STATUS_SUCCESS);
    }
 
@@ -1938,7 +1935,7 @@
    /*
     * Copy the old page
     */
-   MiCopyFromUserPage(NewPage, PAddress);
+   MiCopyFromUserPage(NewPage, Address);
 
    MmLockAddressSpace(AddressSpace);
    /*
@@ -1969,8 +1966,8 @@
    /*
     * Unshare the old page.
     */
-   MmDeleteRmap(OldPage, Process, PAddress);
-   MmInsertRmap(NewPage, Process, PAddress);
+   MmDeleteRmap(OldPage, Process, Address);
+   MmInsertRmap(NewPage, Process, Address);
    MmLockSectionSegment(Segment);
    MmUnsharePageEntrySectionSegment(Section, Segment, Offset, FALSE, FALSE);
    MmUnlockSectionSegment(Segment);


Reply via email to