[NTOS:MM] Improve debug prints in MmCreateVirtualMappingUnsafe. CORE-14478
[reactos.git] / ntoskrnl / mm / i386 / page.c
index 2047f03..e09f121 100644 (file)
 #include <ntoskrnl.h>
 #define NDEBUG
 #include <debug.h>
-#include "../ARM3/miarm.h"
+#include <mm/ARM3/miarm.h>
 
 #if defined (ALLOC_PRAGMA)
 #pragma alloc_text(INIT, MmInitGlobalKernelPageDirectory)
-#pragma alloc_text(INIT, MiInitPageDirectoryMap)
 #endif
 
+#define ADDR_TO_PDE_OFFSET MiAddressToPdeOffset
+#define ADDR_TO_PAGE_TABLE(v)  (((ULONG)(v)) / (1024 * PAGE_SIZE))
 
 /* GLOBALS *****************************************************************/
 
 #define PA_ACCESSED  (1 << PA_BIT_ACCESSED)
 #define PA_GLOBAL    (1 << PA_BIT_GLOBAL)
 
-#define HYPERSPACE          (0xc0400000)
-#define IS_HYPERSPACE(v)    (((ULONG)(v) >= HYPERSPACE && (ULONG)(v) < HYPERSPACE + 0x400000))
+#define IS_HYPERSPACE(v)    (((ULONG)(v) >= HYPER_SPACE && (ULONG)(v) <= HYPER_SPACE_END))
 
 #define PTE_TO_PFN(X)  ((X) >> PAGE_SHIFT)
 #define PFN_TO_PTE(X)  ((X) << PAGE_SHIFT)
 
-#if defined(__GNUC__)
-#define PTE_TO_PAGE(X) ((LARGE_INTEGER)(LONGLONG)(PAGE_MASK(X)))
-#else
-__inline LARGE_INTEGER PTE_TO_PAGE(ULONG npage)
-{
-    LARGE_INTEGER dummy;
-    dummy.QuadPart = (LONGLONG)(PAGE_MASK(npage));
-    return dummy;
-}
-#endif
+#define PAGE_MASK(x)           ((x)&(~0xfff))
 
 const
 ULONG
@@ -146,7 +137,7 @@ ULONG MmProtectToValue[32] =
 
 /* FUNCTIONS ***************************************************************/
 
-BOOLEAN MmUnmapPageTable(PULONG Pt);
+static BOOLEAN MmUnmapPageTable(PULONG Pt);
 
 VOID
 MiFlushTlb(PULONG Pt, PVOID Address)
@@ -198,31 +189,9 @@ ProtectToPTE(ULONG flProtect)
     return(Attributes);
 }
 
-/* Taken from ARM3/pagfault.c */
-BOOLEAN
-FORCEINLINE
-MiSynchronizeSystemPde(PMMPDE PointerPde)
-{
-    MMPDE SystemPde;
-    ULONG Index;
-
-    /* Get the Index from the PDE */
-    Index = ((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE);
-
-    /* Copy the PDE from the double-mapped system page directory */
-    SystemPde = MmSystemPagePtes[Index];
-    *PointerPde = SystemPde;
-
-    /* Make sure we re-read the PDE and PTE */
-    KeMemoryBarrierWithoutFence();
-
-    /* Return, if we had success */
-    return SystemPde.u.Hard.Valid != 0;
-}
-
 NTSTATUS
 NTAPI
-MiDispatchFault(IN BOOLEAN StoreInstruction,
+MiDispatchFault(IN ULONG FaultCode,
                 IN PVOID Address,
                 IN PMMPTE PointerPte,
                 IN PMMPTE PointerProtoPte,
@@ -252,11 +221,11 @@ MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
         {
             PMMPDE PdeBase;
             ULONG PdeOffset = MiGetPdeOffset(Address);
-            
+
             /* Nobody but page fault should ask for creating the PDE,
              * Which imples that Process is the current one */
             ASSERT(Create == FALSE);
-            
+
             PdeBase = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0]));
             if (PdeBase == NULL)
             {
@@ -293,7 +262,8 @@ MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
             ASSERT(PointerPde->u.Long == 0);
 
             MI_WRITE_INVALID_PTE(PointerPde, DemandZeroPde);
-            Status = MiDispatchFault(TRUE,
+            // Tiny HACK: Parameter 1 is the architecture specific FaultCode for an access violation (i.e. page is present)
+            Status = MiDispatchFault(0x1,
                                      Pt,
                                      PointerPde,
                                      NULL,
@@ -301,6 +271,7 @@ MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
                                      PsGetCurrentProcess(),
                                      NULL,
                                      NULL);
+            DBG_UNREFERENCED_LOCAL_VARIABLE(Status);
             ASSERT(KeAreAllApcsDisabled() == TRUE);
             ASSERT(PointerPde->u.Hard.Valid == 1);
         }
@@ -325,7 +296,7 @@ MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
     return Pt;
 }
 
-BOOLEAN MmUnmapPageTable(PULONG Pt)
+static BOOLEAN MmUnmapPageTable(PULONG Pt)
 {
     if (!IS_HYPERSPACE(Pt))
     {
@@ -370,70 +341,7 @@ MmGetPfnForProcess(PEPROCESS Process,
 
 VOID
 NTAPI
-MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN* WasDirty, PPFN_NUMBER Page)
-/*
- * FUNCTION: Delete a virtual mapping
- */
-{
-    BOOLEAN WasValid;
-    ULONG Pte;
-    PULONG Pt;
-
-    Pt = MmGetPageTableForProcess(Process, Address, FALSE);
-    if (Pt == NULL)
-    {
-        KeBugCheck(MEMORY_MANAGEMENT);
-    }
-
-    /*
-     * Atomically disable the present bit and get the old value.
-     */
-    do
-    {
-        Pte = *Pt;
-    } while (Pte != InterlockedCompareExchangePte(Pt, Pte & ~PA_PRESENT, Pte));
-
-    MiFlushTlb(Pt, Address);
-
-    WasValid = (Pte & PA_PRESENT);
-    if (!WasValid)
-    {
-        KeBugCheck(MEMORY_MANAGEMENT);
-    }
-
-    /*
-     * Return some information to the caller
-     */
-    if (WasDirty != NULL)
-    {
-        *WasDirty = Pte & PA_DIRTY;
-    }
-    if (Page != NULL)
-    {
-        *Page = PTE_TO_PFN(Pte);
-    }
-}
-
-VOID
-NTAPI
-MmRawDeleteVirtualMapping(PVOID Address)
-{
-    PULONG Pt;
-
-    Pt = MmGetPageTableForProcess(NULL, Address, FALSE);
-    if (Pt && *Pt)
-    {
-        /*
-         * Set the entry to zero
-         */
-        InterlockedExchangePte(Pt, 0);
-        MiFlushTlb(Pt, Address);
-    }
-}
-
-VOID
-NTAPI
-MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN FreePage,
+MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address,
                        BOOLEAN* WasDirty, PPFN_NUMBER Page)
 /*
  * FUNCTION: Delete a virtual mapping
@@ -444,8 +352,8 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN FreePage,
     ULONG Pte;
     PULONG Pt;
 
-    DPRINT("MmDeleteVirtualMapping(%x, %x, %d, %x, %x)\n",
-           Process, Address, FreePage, WasDirty, Page);
+    DPRINT("MmDeleteVirtualMapping(%p, %p, %p, %p)\n",
+           Process, Address, WasDirty, Page);
 
     Pt = MmGetPageTableForProcess(Process, Address, FALSE);
 
@@ -485,12 +393,6 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN FreePage,
                }
 
         Pfn = PTE_TO_PFN(Pte);
-
-        if (FreePage)
-        {
-            MmReleasePageMemoryConsumer(MC_SYSTEM, Pfn);
-            Pfn = 0;
-        }
     }
     else
     {
@@ -575,7 +477,7 @@ Mmi386MakeKernelPageTableGlobal(PVOID Address)
 {
     PMMPDE PointerPde = MiAddressToPde(Address);
     PMMPTE PointerPte = MiAddressToPte(Address);
-    
+
     if (PointerPde->u.Hard.Valid == 0)
     {
         if(!MiSynchronizeSystemPde(PointerPde))
@@ -666,35 +568,6 @@ MmSetDirtyPage(PEPROCESS Process, PVOID Address)
     }
 }
 
-VOID
-NTAPI
-MmEnableVirtualMapping(PEPROCESS Process, PVOID Address)
-{
-    PULONG Pt;
-    ULONG Pte;
-
-    Pt = MmGetPageTableForProcess(Process, Address, FALSE);
-    if (Pt == NULL)
-    {
-        //HACK to get DPH working, waiting for MM rewrite :-/
-        //KeBugCheck(MEMORY_MANAGEMENT);
-        return;
-    }
-
-    /* Do not mark a 0 page as present */
-    if(0 == InterlockedCompareExchangePte(Pt, 0, 0))
-        return;
-
-    do
-    {
-        Pte = *Pt;
-    } while (Pte != InterlockedCompareExchangePte(Pt, Pte | PA_PRESENT, Pte));
-
-    /* We don't need to flush the TLB here because it
-     * won't cache translations for non-present pages */
-    MmUnmapPageTable(Pt);
-}
-
 BOOLEAN
 NTAPI
 MmIsPagePresent(PEPROCESS Process, PVOID Address)
@@ -791,7 +664,7 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
     ULONG oldPdeOffset, PdeOffset;
     PULONG Pt = NULL;
     ULONG Pte;
-    DPRINT("MmCreateVirtualMappingUnsafe(%x, %x, %x, %x (%x), %d)\n",
+    DPRINT("MmCreateVirtualMappingUnsafe(%p, %p, %lu, %p (%x), %lu)\n",
            Process, Address, flProtect, Pages, *Pages, PageCount);
 
     ASSERT(((ULONG_PTR)Address % PAGE_SIZE) == 0);
@@ -800,13 +673,13 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
     {
         if (Address < MmSystemRangeStart)
         {
-            DPRINT1("No process\n");
+            DPRINT1("NULL process given for user-mode mapping at %p -- %lu pages starting at %Ix\n", Address, PageCount, *Pages);
             KeBugCheck(MEMORY_MANAGEMENT);
         }
         if (PageCount > 0x10000 ||
             (ULONG_PTR) Address / PAGE_SIZE + PageCount > 0x100000)
         {
-            DPRINT1("Page count too large\n");
+            DPRINT1("Page count too large for kernel-mode mapping at %p -- %lu pages starting at %Ix\n", Address, PageCount, *Pages);
             KeBugCheck(MEMORY_MANAGEMENT);
         }
     }
@@ -814,14 +687,14 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
     {
         if (Address >= MmSystemRangeStart)
         {
-            DPRINT1("Setting kernel address with process context\n");
+            DPRINT1("Process %p given for kernel-mode mapping at %p -- %lu pages starting at %Ix\n", Process, Address, PageCount, *Pages);
             KeBugCheck(MEMORY_MANAGEMENT);
         }
         if (PageCount > (ULONG_PTR)MmSystemRangeStart / PAGE_SIZE ||
             (ULONG_PTR) Address / PAGE_SIZE + PageCount >
             (ULONG_PTR)MmSystemRangeStart / PAGE_SIZE)
         {
-            DPRINT1("Page Count too large\n");
+            DPRINT1("Page count too large for process %p user-mode mapping at %p -- %lu pages starting at %Ix\n", Process, Address, PageCount, *Pages);
             KeBugCheck(MEMORY_MANAGEMENT);
         }
     }
@@ -846,7 +719,7 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
         if (!(Attributes & PA_PRESENT) && Pages[i] != 0)
         {
             DPRINT1("Setting physical address but not allowing access at address "
-                    "0x%.8X with attributes %x/%x.\n",
+                    "0x%p with attributes %x/%x.\n",
                     Addr, Attributes, flProtect);
             KeBugCheck(MEMORY_MANAGEMENT);
         }
@@ -871,7 +744,7 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
         /* There should not be anything valid here */
         if (Pte != 0)
         {
-            DPRINT1("Bad PTE %lx\n", Pte);
+            DPRINT1("Bad PTE %lx at %p for %p + %lu\n", Pte, Pt, Address, i);
             KeBugCheck(MEMORY_MANAGEMENT);
         }
 
@@ -968,7 +841,7 @@ MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
     PULONG Pt;
     ULONG Pte;
 
-    DPRINT("MmSetPageProtect(Process %x  Address %x  flProtect %x)\n",
+    DPRINT("MmSetPageProtect(Process %p  Address %p  flProtect %x)\n",
            Process, Address, flProtect);
 
     Attributes = ProtectToPTE(flProtect);
@@ -1003,32 +876,6 @@ MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
         MmUnmapPageTable(Pt);
 }
 
-/*
- * @implemented
- */
-PHYSICAL_ADDRESS NTAPI
-MmGetPhysicalAddress(PVOID vaddr)
-/*
- * FUNCTION: Returns the physical address corresponding to a virtual address
- */
-{
-    PHYSICAL_ADDRESS p;
-    ULONG Pte;
-
-    DPRINT("MmGetPhysicalAddress(vaddr %x)\n", vaddr);
-    Pte = MmGetPageEntryForProcess(NULL, vaddr);
-    if (Pte != 0 && (Pte & PA_PRESENT))
-    {
-        p.QuadPart = PAGE_MASK(Pte);
-        p.u.LowPart |= (ULONG_PTR)vaddr & (PAGE_SIZE - 1);
-    }
-    else
-    {
-        p.QuadPart = 0;
-    }
-    return p;
-}
-
 VOID
 INIT_FUNCTION
 NTAPI