- Implemented a kernel mapping region which is process local. 
  This mapping can be used to map temporary memory pages from 
  other process's like  pde's/pte's. It is also used to make 
  a copy of a page or to clean a page.
Modified: trunk/reactos/ntoskrnl/Makefile
Modified: trunk/reactos/ntoskrnl/include/internal/mm.h
Modified: trunk/reactos/ntoskrnl/ke/i386/multiboot.S
Modified: trunk/reactos/ntoskrnl/mm/freelist.c
Modified: trunk/reactos/ntoskrnl/mm/i386/page.c
Modified: trunk/reactos/ntoskrnl/mm/kmap.c
Modified: trunk/reactos/ntoskrnl/mm/mminit.c
Modified: trunk/reactos/ntoskrnl/mm/section.c

Modified: trunk/reactos/ntoskrnl/Makefile
--- trunk/reactos/ntoskrnl/Makefile	2005-01-25 22:36:28 UTC (rev 13287)
+++ trunk/reactos/ntoskrnl/Makefile	2005-01-25 22:50:47 UTC (rev 13288)
@@ -148,7 +148,6 @@
 	mm/region.o \
 	mm/rmap.o \
 	mm/section.o \
-	mm/slab.o \
 	mm/verifier.o \
 	mm/virtual.o \
 	mm/wset.o

Modified: trunk/reactos/ntoskrnl/include/internal/mm.h
--- trunk/reactos/ntoskrnl/include/internal/mm.h	2005-01-25 22:36:28 UTC (rev 13287)
+++ trunk/reactos/ntoskrnl/include/internal/mm.h	2005-01-25 22:50:47 UTC (rev 13288)
@@ -551,8 +551,6 @@
 
 VOID ExUnmapPage(PVOID Addr);
 
-VOID MiInitKernelMap(VOID);
-
 PVOID ExAllocatePageWithPhysPage(PFN_TYPE Page);
 
 NTSTATUS MiCopyFromUserPage(PFN_TYPE Page, PVOID SourceAddress);
@@ -649,6 +647,12 @@
 
 /* i386/page.c *********************************************************/
 
+PVOID MmCreateHyperspaceMapping(PFN_TYPE Page);
+
+PFN_TYPE MmChangeHyperspaceMapping(PVOID Address, PFN_TYPE Page);
+
+PFN_TYPE MmDeleteHyperspaceMapping(PVOID Address);
+
 NTSTATUS MmCreateVirtualMappingForKernel(PVOID Address, 
 					 ULONG flProtect,
 					 PPFN_TYPE Pages,

Modified: trunk/reactos/ntoskrnl/ke/i386/multiboot.S
--- trunk/reactos/ntoskrnl/ke/i386/multiboot.S	2005-01-25 22:36:28 UTC (rev 13287)
+++ trunk/reactos/ntoskrnl/ke/i386/multiboot.S	2005-01-25 22:50:47 UTC (rev 13288)
@@ -114,7 +114,7 @@
 	movl	$(V2P(kernel_pagetable+4096) + 0x3), ((KERNEL_BASE >> 20) + 4)(%esi)
 
 	movl	$(V2P(startup_pagedirectory) + 0x3), 0xF00(%esi) 
-	movl	$(V2P(kernelmap_pagetable) + 0x3), 0xF0C(%esi)
+	movl	$(V2P(hyperspace_pagetable) + 0x3), 0xF08(%esi)
 #ifdef CONFIG_SMP
 	movl	$(V2P(apic_pagetable) + 0x3), 0xFEC(%esi)
 #endif /* CONFIG_SMP */
@@ -351,8 +351,9 @@
 kernel_pagetable:
 	.fill 2*4096, 1, 0
 
-kernelmap_pagetable:
+hyperspace_pagetable:
 	.fill 4096, 1, 0
+	
 _pae_pagedirtable:
 	.fill 4096, 1, 0
 #ifdef CONFIG_SMP

Modified: trunk/reactos/ntoskrnl/mm/freelist.c
--- trunk/reactos/ntoskrnl/mm/freelist.c	2005-01-25 22:36:28 UTC (rev 13287)
+++ trunk/reactos/ntoskrnl/mm/freelist.c	2005-01-25 22:50:47 UTC (rev 13288)
@@ -56,9 +56,10 @@
 static LIST_ENTRY FreeUnzeroedPageListHead;
 static LIST_ENTRY BiosPageListHead;
 
-static HANDLE ZeroPageThreadHandle;
+static PETHREAD ZeroPageThread;
 static CLIENT_ID ZeroPageThreadId;
 static KEVENT ZeroPageThreadEvent;
+static BOOLEAN ZeroPageThreadShouldTerminate = FALSE;
 
 static ULONG UnzeroedPageCount = 0;
 
@@ -381,6 +382,11 @@
             KEBUGCHECK(0);
          }
       }
+      else
+      {
+         /* Setting the page protection is necessary to set the global bit on IA32 */
+         MmSetPageProtect(NULL, Address, PAGE_READWRITE);
+      }
       memset(Address, 0, PAGE_SIZE);
       
       start = ((ULONG_PTR)Address - (ULONG_PTR)MmPageArray) / sizeof(PHYSICAL_PAGE);
@@ -1046,7 +1052,7 @@
    return NumberOfPagesFound;
 }
 
-NTSTATUS STDCALL
+VOID STDCALL
 MmZeroPageThreadMain(PVOID Ignored)
 {
    NTSTATUS Status;
@@ -1054,7 +1060,6 @@
    PLIST_ENTRY ListEntry;
    PPHYSICAL_PAGE PageDescriptor;
    PFN_TYPE Pfn;
-   static PVOID Address = NULL;
    ULONG Count;
 
    while(1)
@@ -1068,9 +1073,14 @@
       {
          DbgPrint("ZeroPageThread: Wait failed\n");
          KEBUGCHECK(0);
-         return(STATUS_UNSUCCESSFUL);
+         return;
       }
 
+      if (ZeroPageThreadShouldTerminate)
+      {
+         DbgPrint("ZeroPageThread: Terminating\n");
+	 return;
+      }
       Count = 0;
       KeAcquireSpinLock(&PageListLock, &oldIrql);
       while (!IsListEmpty(&FreeUnzeroedPageListHead))
@@ -1081,27 +1091,9 @@
          /* We set the page to used, because MmCreateVirtualMapping failed with unused pages */
          PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED;
          KeReleaseSpinLock(&PageListLock, oldIrql);
-         Count++;
          Pfn = PageDescriptor - MmPageArray;
-         if (Address == NULL)
-         {
-            Address = ExAllocatePageWithPhysPage(Pfn);
-         }
-         else
-         {
-            Status = MmCreateVirtualMapping(NULL,
-                                            Address,
-                                            PAGE_READWRITE | PAGE_SYSTEM,
-                                            &Pfn,
-                                            1);
-            if (!NT_SUCCESS(Status))
-            {
-               DbgPrint("Unable to create virtual mapping\n");
-               KEBUGCHECK(0);
-            }
-         }
-         memset(Address, 0, PAGE_SIZE);
-         MmDeleteVirtualMapping(NULL, (PVOID)Address, FALSE, NULL, NULL);
+         Status = MiZeroPage(Pfn);
+
          KeAcquireSpinLock(&PageListLock, &oldIrql);
          if (PageDescriptor->MapCount != 0)
          {
@@ -1110,7 +1102,17 @@
          }
 	 PageDescriptor->Flags.Zero = 1;
          PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_FREE;
-         InsertHeadList(&FreeZeroedPageListHead, ListEntry);
+         if (NT_SUCCESS(Status))
+         {
+            InsertHeadList(&FreeZeroedPageListHead, ListEntry);
+            Count++;
+         }
+         else
+         {
+            InsertHeadList(&FreeUnzeroedPageListHead, ListEntry);
+            UnzeroedPageCount++;
+         }
+
       }
       DPRINT("Zeroed %d pages.\n", Count);
       KeResetEvent(&ZeroPageThreadEvent);
@@ -1121,28 +1123,36 @@
 NTSTATUS INIT_FUNCTION
 MmInitZeroPageThread(VOID)
 {
-   KPRIORITY Priority;
    NTSTATUS Status;
-
-   Status = PsCreateSystemThread(&ZeroPageThreadHandle,
+   HANDLE ThreadHandle;
+   
+   ZeroPageThreadShouldTerminate = FALSE;
+   Status = PsCreateSystemThread(&ThreadHandle,
                                  THREAD_ALL_ACCESS,
                                  NULL,
                                  NULL,
                                  &ZeroPageThreadId,
-                                 (PKSTART_ROUTINE) MmZeroPageThreadMain,
+                                 MmZeroPageThreadMain,
                                  NULL);
    if (!NT_SUCCESS(Status))
    {
-      return(Status);
+      KEBUGCHECK(0);
    }
 
-   Priority = 1;
-   NtSetInformationThread(ZeroPageThreadHandle,
-                          ThreadPriority,
-                          &Priority,
-                          sizeof(Priority));
+   Status = ObReferenceObjectByHandle(ThreadHandle,
+				      THREAD_ALL_ACCESS,
+				      PsThreadType,
+				      KernelMode,
+				      (PVOID*)&ZeroPageThread,
+				      NULL);
+   if (!NT_SUCCESS(Status))
+     {
+	KEBUGCHECK(0);
+     }
 
-   return(STATUS_SUCCESS);
+   KeSetPriorityThread(&ZeroPageThread->Tcb, LOW_PRIORITY);
+   NtClose(ThreadHandle);
+   return STATUS_SUCCESS;
 }
 
 /* EOF */

Modified: trunk/reactos/ntoskrnl/mm/i386/page.c
--- trunk/reactos/ntoskrnl/mm/i386/page.c	2005-01-25 22:36:28 UTC (rev 13287)
+++ trunk/reactos/ntoskrnl/mm/i386/page.c	2005-01-25 22:50:47 UTC (rev 13288)
@@ -52,11 +52,14 @@
 #define PA_ACCESSED  (1 << PA_BIT_ACCESSED)
 #define PA_GLOBAL    (1 << PA_BIT_GLOBAL)
 
-#define PAGETABLE_MAP     (0xf0000000)
-#define PAGEDIRECTORY_MAP (0xf0000000 + (PAGETABLE_MAP / (1024)))
+#define PAGETABLE_MAP		(0xf0000000)
+#define PAGEDIRECTORY_MAP	(0xf0000000 + (PAGETABLE_MAP / (1024)))
 
 #define PAE_PAGEDIRECTORY_MAP	(0xf0000000 + (PAGETABLE_MAP / (512)))
 
+#define HYPERSPACE		(0xf0800000)  
+#define IS_HYPERSPACE(v)	(((ULONG)(v) >= 0xF0800000 && (ULONG)(v) < 0xF0C00000))
+
 ULONG MmGlobalKernelPageDirectory[1024];
 ULONGLONG MmGlobalKernelPageDirectoryForPAE[2048];
 
@@ -237,12 +240,12 @@
       PULONGLONG Pde;
       ULONG k;
 
-      PageDirTable = (PULONGLONG)ExAllocatePageWithPhysPage(Process->Pcb.DirectoryTableBase.QuadPart >> PAGE_SHIFT);
+      PageDirTable = (PULONGLONG)MmCreateHyperspaceMapping(PAE_PTE_TO_PFN(Process->Pcb.DirectoryTableBase.QuadPart));
       for (i = 0; i < 4; i++)
       {
+         PageDir = (PULONGLONG)MmCreateHyperspaceMapping(PAE_PTE_TO_PFN(PageDirTable[i]));
          if (i < PAE_ADDR_TO_PDTE_OFFSET(KERNEL_BASE))
 	 {
-            PageDir = (PULONGLONG)ExAllocatePageWithPhysPage(PageDirTable[i] >> PAGE_SHIFT);
 	    for (j = 0; j < 512; j++)
 	    {
 	       if (PageDir[j] != 0LL)
@@ -251,7 +254,7 @@
 		          Process->UniqueProcessId,
 	                  (i * 512 + j) * 512 * PAGE_SIZE, (i * 512 + j + 1) * 512 * PAGE_SIZE - 1, 
 		          Process->AddressSpace.PageTableRefCountTable[i*512 + j]);
-                  Pde = ExAllocatePageWithPhysPage(PageDir[j] >> PAGE_SHIFT);
+                  Pde = MmCreateHyperspaceMapping(PAE_PTE_TO_PFN(PageDir[j]));
 	          for (k = 0; k < 512; k++)
 	          {
 	             if(Pde[k] != 0)
@@ -268,21 +271,27 @@
 	                }
 		     }
 		  }
-		  ExUnmapPage(Pde);
+		  MmDeleteHyperspaceMapping(Pde);
 	    	  MmReleasePageMemoryConsumer(MC_NPPOOL, PAE_PTE_TO_PFN(PageDir[j]));
 	       }
 	    }
-	    ExUnmapPage(PageDir);
 	 }
-         MmReleasePageMemoryConsumer(MC_NPPOOL, PageDirTable[i] >> PAGE_SHIFT);
+	 else
+	 {
+	    MmReleasePageMemoryConsumer(MC_NPPOOL, PAE_PTE_TO_PFN(PageDir[PAE_ADDR_TO_PDE_PAGE_OFFSET(HYPERSPACE)]));
+	    MmReleasePageMemoryConsumer(MC_NPPOOL, PAE_PTE_TO_PFN(PageDir[PAE_ADDR_TO_PDE_PAGE_OFFSET(HYPERSPACE)+1]));
+	 }
+	 MmDeleteHyperspaceMapping(PageDir);
+         MmReleasePageMemoryConsumer(MC_NPPOOL, PAE_PTE_TO_PFN(PageDirTable[i]));
       }
-      ExUnmapPage((PVOID)PageDirTable);
+      MmDeleteHyperspaceMapping((PVOID)PageDirTable);
+      MmReleasePageMemoryConsumer(MC_NPPOOL, PAE_PTE_TO_PFN(Process->Pcb.DirectoryTableBase.QuadPart));
    }
    else
    {
       PULONG Pde;
       PULONG PageDir;
-      PageDir = ExAllocatePageWithPhysPage(Process->Pcb.DirectoryTableBase.QuadPart >> PAGE_SHIFT);
+      PageDir = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase.u.LowPart));
       for (i = 0; i < ADDR_TO_PDE_OFFSET(KERNEL_BASE); i++)
       {
          if (PageDir[i] != 0)
@@ -290,7 +299,7 @@
             DPRINT1("Pde for %08x - %08x is not freed, RefCount %d\n", 
 	            i * 4 * 1024 * 1024, (i + 1) * 4 * 1024 * 1024 - 1, 
 		    Process->AddressSpace.PageTableRefCountTable[i]);
-	    Pde = ExAllocatePageWithPhysPage(PageDir[i] >> PAGE_SHIFT);
+	    Pde = MmCreateHyperspaceMapping(PTE_TO_PFN(PageDir[i]));
 	    for (j = 0; j < 1024; j++)
 	    {
 	       if(Pde[j] != 0)
@@ -307,14 +316,15 @@
 	          }
 	       }
 	    }
-	    ExUnmapPage(Pde);
+	    MmDeleteHyperspaceMapping(Pde);
 	    MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PFN(PageDir[i]));
 	 }
       }
-      ExUnmapPage(PageDir);
+      MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PFN(PageDir[ADDR_TO_PDE_OFFSET(HYPERSPACE)]));
+      MmDeleteHyperspaceMapping(PageDir);
+      MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PFN(Process->Pcb.DirectoryTableBase.u.LowPart));
    }
 
-   MmReleasePageMemoryConsumer(MC_NPPOOL, Process->Pcb.DirectoryTableBase.QuadPart >> PAGE_SHIFT);
 #if defined(__GNUC__)
 
    Process->Pcb.DirectoryTableBase.QuadPart = 0LL;
@@ -329,87 +339,75 @@
 
 NTSTATUS MmCopyMmInfo(PEPROCESS Src, PEPROCESS Dest)
 {
-   PHYSICAL_ADDRESS PhysPageDirectory;
    PKPROCESS KProcess = &Dest->Pcb;
-
+   NTSTATUS Status;
+   ULONG i, j;
+   PFN_TYPE Pfn[7];
+   ULONG Count;
+   
    DPRINT("MmCopyMmInfo(Src %x, Dest %x)\n", Src, Dest);
 
+   Count = Ke386Pae ? 7 : 2;
+
+   for (i = 0; i < Count; i++)
+   {
+      Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn[i]);
+      if (!NT_SUCCESS(Status))
+      {
+	 for (j = 0; j < i; j++)
+	 {
+	    MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn[j]);
+	 }
+	 return Status;
+      }
+   }
+
    if (Ke386Pae)
    {
       PULONGLONG PageDirTable;
       PULONGLONG PageDir;
-      PFN_TYPE Pfn[4];
-      ULONG i, j;
-      NTSTATUS Status;
 
-      PageDirTable = ExAllocatePage();
-      if (PageDirTable == NULL)
-      {
-         return STATUS_UNSUCCESSFUL;
-      }
-      PhysPageDirectory = MmGetPhysicalAddress(PageDirTable);
-
+      PageDirTable = MmCreateHyperspaceMapping(Pfn[0]);
       for (i = 0; i < 4; i++)
       {
-         Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn[i]);
-	 if (!NT_SUCCESS(Status))
-	 {
-	    for (j = 0; j < i; j++)
-	    {
-	       MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn[j]);
-	    }
-	    ExUnmapPage(PageDirTable);
-	    MmReleasePageMemoryConsumer(MC_NPPOOL, PhysPageDirectory.QuadPart >> PAGE_SHIFT);
-	    return Status;
-	 }
-	 PageDirTable[i] = (Pfn[i] << PAGE_SHIFT) | PA_PRESENT;
+	 PageDirTable[i] = PAE_PFN_TO_PTE(Pfn[1+i]) | PA_PRESENT;
       }
-      ExUnmapPage(PageDirTable);
+      MmDeleteHyperspaceMapping(PageDirTable);
       for (i = PAE_ADDR_TO_PDTE_OFFSET(KERNEL_BASE); i < 4; i++)
       {
-         PageDir = (PULONGLONG)ExAllocatePageWithPhysPage(Pfn[i]);
-         if (PageDir == NULL)
-         {
-	    for (j = 0; j < 4; j++)
-	    {
-	       MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn[j]);
-	    }
-	    ExUnmapPage(PageDirTable);
-	    MmReleasePageMemoryConsumer(MC_NPPOOL, PhysPageDirectory.QuadPart >> PAGE_SHIFT);
-	    return STATUS_UNSUCCESSFUL;
-         }
+         PageDir = (PULONGLONG)MmCreateHyperspaceMapping(Pfn[i+1]);
          memcpy(PageDir, &MmGlobalKernelPageDirectoryForPAE[i * 512], 512 * sizeof(ULONGLONG));
 	 if (PAE_ADDR_TO_PDTE_OFFSET(PAGETABLE_MAP) == i)
 	 {
             for (j = 0; j < 4; j++)
             {
-               PageDir[PAE_ADDR_TO_PDE_PAGE_OFFSET(PAGETABLE_MAP) + j] = (Pfn[j] << PAGE_SHIFT) | PA_PRESENT | PA_READWRITE;
+               PageDir[PAE_ADDR_TO_PDE_PAGE_OFFSET(PAGETABLE_MAP) + j] = PAE_PFN_TO_PTE(Pfn[1+j]) | PA_PRESENT | PA_READWRITE;
             }
 	 }
-         ExUnmapPage(PageDir);
+	 if (PAE_ADDR_TO_PDTE_OFFSET(HYPERSPACE) == i)
+	 {
+	    PageDir[PAE_ADDR_TO_PDE_PAGE_OFFSET(HYPERSPACE)] = PAE_PFN_TO_PTE(Pfn[5]) | PA_PRESENT | PA_READWRITE;
+	    PageDir[PAE_ADDR_TO_PDE_PAGE_OFFSET(HYPERSPACE)+1] = PAE_PFN_TO_PTE(Pfn[6]) | PA_PRESENT | PA_READWRITE;
+	 }
+         MmDeleteHyperspaceMapping(PageDir);
       }
    }
    else
    {
       PULONG PageDirectory;
-      PageDirectory = ExAllocatePage();
-      if (PageDirectory == NULL)
-      {
-         return(STATUS_UNSUCCESSFUL);
-      }
-      PhysPageDirectory = MmGetPhysicalAddress(PageDirectory);
+      PageDirectory = MmCreateHyperspaceMapping(Pfn[0]);
 
       memcpy(PageDirectory + ADDR_TO_PDE_OFFSET(KERNEL_BASE),
              MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(KERNEL_BASE),
              (1024 - ADDR_TO_PDE_OFFSET(KERNEL_BASE)) * sizeof(ULONG));
 
-      DPRINT("Addr %x\n",PAGETABLE_MAP / (4*1024*1024));
-      PageDirectory[PAGETABLE_MAP / (4*1024*1024)] =
-         PhysPageDirectory.u.LowPart | PA_PRESENT | PA_READWRITE;
+      DPRINT("Addr %x\n",ADDR_TO_PDE_OFFSET(PAGETABLE_MAP));
+      PageDirectory[ADDR_TO_PDE_OFFSET(PAGETABLE_MAP)] = PFN_TO_PTE(Pfn[0]) | PA_PRESENT | PA_READWRITE;
+      PageDirectory[ADDR_TO_PDE_OFFSET(HYPERSPACE)] = PFN_TO_PTE(Pfn[1]) | PA_PRESENT | PA_READWRITE;
 
-      ExUnmapPage(PageDirectory);
+      MmDeleteHyperspaceMapping(PageDirectory);
    }
-   KProcess->DirectoryTableBase = PhysPageDirectory;
+   KProcess->DirectoryTableBase.QuadPart = PFN_TO_PTE(Pfn[0]);
    DPRINT("Finished MmCopyMmInfo()\n");
    return(STATUS_SUCCESS);
 }
@@ -524,13 +522,13 @@
    }
    if (Address < (PVOID)KERNEL_BASE && Process && Process != PsGetCurrentProcess())
    {
-      PageDirTable = ExAllocatePageWithPhysPage(Process->Pcb.DirectoryTableBase.QuadPart >> PAGE_SHIFT);
+      PageDirTable = MmCreateHyperspaceMapping(PAE_PTE_TO_PFN(Process->Pcb.DirectoryTableBase.QuadPart));
       if (PageDirTable == NULL)
       {
          KEBUGCHECK(0);
       }
-      PageDir = ExAllocatePageWithPhysPage(PageDirTable[PAE_ADDR_TO_PDTE_OFFSET(Address)] >> PAGE_SHIFT);
-      ExUnmapPage(PageDirTable);
+      PageDir = MmCreateHyperspaceMapping(PAE_PTE_TO_PFN(PageDirTable[PAE_ADDR_TO_PDTE_OFFSET(Address)]));
+      MmDeleteHyperspaceMapping(PageDirTable);
       if (PageDir == NULL)
       {
          KEBUGCHECK(0);
@@ -541,7 +539,7 @@
       {
          if (Create == FALSE)
 	 {
-	    ExUnmapPage(PageDir);
+	    MmDeleteHyperspaceMapping(PageDir);
 	    return NULL;
 	 }
          Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
@@ -561,8 +559,8 @@
       {
          Pfn = PAE_PTE_TO_PFN(Entry);
       }
-      ExUnmapPage(PageDir);
-      Pt = ExAllocatePageWithPhysPage(Pfn);
+      MmDeleteHyperspaceMapping(PageDir);
+      Pt = MmCreateHyperspaceMapping(Pfn);
       if (Pt == NULL)
       {
          KEBUGCHECK(0);
@@ -630,7 +628,7 @@
    
    if (Address < (PVOID)KERNEL_BASE && Process && Process != PsGetCurrentProcess())
    {
-      PageDir = ExAllocatePageWithPhysPage(Process->Pcb.DirectoryTableBase.QuadPart >> PAGE_SHIFT);
+      PageDir = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase.QuadPart));
       if (PageDir == NULL)
       {
          KEBUGCHECK(0);
@@ -639,7 +637,7 @@
       {
          if (Create == FALSE)
 	 {
-	    ExUnmapPage(PageDir);
+	    MmDeleteHyperspaceMapping(PageDir);
 	    return NULL;
 	 }
          Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
@@ -658,8 +656,8 @@
       {
          Pfn = PTE_TO_PFN(PageDir[PdeOffset]);
       }
-      ExUnmapPage(PageDir);
-      Pt = ExAllocatePageWithPhysPage(Pfn);
+      MmDeleteHyperspaceMapping(PageDir);
+      Pt = MmCreateHyperspaceMapping(Pfn);
       if (Pt == NULL)
       {
          KEBUGCHECK(0);
@@ -733,7 +731,7 @@
    }
    if (Pt)
    {
-      ExUnmapPage((PVOID)PAGE_ROUND_DOWN(Pt));
+      MmDeleteHyperspaceMapping((PVOID)PAGE_ROUND_DOWN(Pt));
    }
    return FALSE;
 }
@@ -1907,7 +1905,7 @@
    {
       if (!MmIsUsablePage(Pages[i]))
       {
-         DPRINT1("Page at address %x not usable\n", Pages[i] << PAGE_SHIFT);
+         DPRINT1("Page at address %x not usable\n", PFN_TO_PTE(Pages[i]));
          KEBUGCHECK(0);
       }
    }
@@ -2075,6 +2073,176 @@
    return p;
 }
 
+PVOID
+MmCreateHyperspaceMapping(PFN_TYPE Page)
+{
+   PVOID Address;
+   LONG i;
+
+   if (Ke386Pae)
+   {
+      ULONGLONG Entry;
+      ULONGLONG ZeroEntry = 0LL;
+      PULONGLONG Pte;
+
+      Entry = PFN_TO_PTE(Page) | PA_PRESENT | PA_READWRITE;
+      Pte = PAE_ADDR_TO_PTE(HYPERSPACE) + Page % 1024;
+
+      if (Page & 1024)
+      {
+         for (i = Page %1024; i < 1024; i++, Pte++)
+         {
+            if (0LL == ExfInterlockedCompareExchange64UL(Pte, &Entry, &ZeroEntry))
+	    {
+	       break;
+	    }
+         }
+         if (i >= 1024)
+         {
+            Pte = PAE_ADDR_TO_PTE(HYPERSPACE);
+	    for (i = 0; i < Page % 1024; i++, Pte++)
+	    {
+               if (0LL == ExfInterlockedCompareExchange64UL(Pte, &Entry, &ZeroEntry))
+	       {
+	          break;
+	       }
+	    }
+	    if (i >= Page % 1024)
+	    {
+	       KEBUGCHECK(0);
+	    }
+         }
+      }
+      else 
+      {
+         for (i = Page %1024; i >= 0; i--, Pte--)
+         {
+            if (0LL == ExfInterlockedCompareExchange64UL(Pte, &Entry, &ZeroEntry))
+	    {
+	       break;
+	    }
+         }
+         if (i < 0)
+         {
+            Pte = PAE_ADDR_TO_PTE(HYPERSPACE) + 1023;
+	    for (i = 1023; i > Page % 1024; i--, Pte--)
+	    {
+               if (0LL == ExfInterlockedCompareExchange64UL(Pte, &Entry, &ZeroEntry))
+	       {
+	          break;
+	       }
+	    }
+	    if (i <= Page % 1024)
+	    {
+	       KEBUGCHECK(0);
+	    }
+         }
+      }
+   }
+   else
+   {
+      ULONG Entry;
+      PULONG Pte;
+      Entry = PFN_TO_PTE(Page) | PA_PRESENT | PA_READWRITE;
+      Pte = ADDR_TO_PTE(HYPERSPACE) + Page % 1024;
+      if (Page & 1024)
+      {
+         for (i = Page % 1024; i < 1024; i++, Pte++)
+         {
+            if (0 == InterlockedCompareExchange((PLONG)Pte, (LONG)Entry, 0))
+            {
+               break;
+            }
+         }
+         if (i >= 1024)
+         {
+            Pte = ADDR_TO_PTE(HYPERSPACE);
+            for (i = 0; i < Page % 1024; i++, Pte++)
+            {
+               if (0 == InterlockedCompareExchange((PLONG)Pte, (LONG)Entry, 0))
+               {
+                  break;
+               }
+            }
+            if (i >= Page % 1024)
+            {
+               KEBUGCHECK(0);
+            }
+         }
+      }
+      else
+      {
+         for (i = Page % 1024; i >= 0; i--, Pte--)
+         {
+            if (0 == InterlockedCompareExchange((PLONG)Pte, (LONG)Entry, 0))
+            {
+               break;
+            }
+         }
+         if (i < 0)
+         {
+            Pte = ADDR_TO_PTE(HYPERSPACE) + 1023;
+            for (i = 1023; i > Page % 1024; i--, Pte--)
+            {
+               if (0 == InterlockedCompareExchange((PLONG)Pte, (LONG)Entry, 0))
+               {
+                  break;
+               }
+            }
+            if (i <= Page % 1024)
+            {
+               KEBUGCHECK(0);
+            }
+         }
+      }
+   }
+   Address = (PVOID)HYPERSPACE + i * PAGE_SIZE;
+   FLUSH_TLB_ONE(Address);
+   return Address;
+}
+
+PFN_TYPE 
+MmChangeHyperspaceMapping(PVOID Address, PFN_TYPE NewPage)
+{
+   PFN_TYPE Pfn;
+   ASSERT (IS_HYPERSPACE(Address));
+   if (Ke386Pae)
+   {
+      ULONGLONG Entry = PAE_PFN_TO_PTE(NewPage) | PA_PRESENT | PA_READWRITE;
+      Entry = (ULONG)ExfpInterlockedExchange64UL(PAE_ADDR_TO_PTE(Address), &Entry);
+      Pfn = PAE_PTE_TO_PFN(Entry);
+   }
+   else
+   {
+      ULONG Entry;
+      Entry = InterlockedExchange(ADDR_TO_PTE(Address), PFN_TO_PTE(NewPage) | PA_PRESENT | PA_READWRITE);
+      Pfn = PTE_TO_PFN(Entry);
+   }
+   FLUSH_TLB_ONE(Address);
+   return Pfn;
+}
+
+PFN_TYPE
+MmDeleteHyperspaceMapping(PVOID Address)
+{
+   PFN_TYPE Pfn;
+   ASSERT (IS_HYPERSPACE(Address));
+   if (Ke386Pae)
+   {
+      ULONGLONG Entry = 0LL;
+      Entry = (ULONG)ExfpInterlockedExchange64UL(PAE_ADDR_TO_PTE(Address), &Entry);
+      Pfn = PAE_PTE_TO_PFN(Entry);
+   }
+   else
+   {
+      ULONG Entry;
+      Entry = InterlockedExchange(ADDR_TO_PTE(Address), 0);
+      Pfn = PTE_TO_PFN(Entry);
+   }
+   FLUSH_TLB_ONE(Address);
+   return Pfn;
+}
+
 VOID MmUpdatePageDir(PEPROCESS Process, PVOID Address, ULONG Size)
 {
    ULONG StartOffset, EndOffset, Offset; 
@@ -2111,9 +2279,9 @@
 
          if (Process != NULL && Process != PsGetCurrentProcess())
          {
-            PageDirTable = ExAllocatePageWithPhysPage(Process->Pcb.DirectoryTableBase.u.LowPart >> PAGE_SHIFT);
-            Pde = (PULONGLONG)ExAllocatePageWithPhysPage(PageDirTable[i] >> PAGE_SHIFT);
-	    ExUnmapPage(PageDirTable);
+            PageDirTable = MmCreateHyperspaceMapping(PAE_PTE_TO_PFN(Process->Pcb.DirectoryTableBase.QuadPart));
+            Pde = (PULONGLONG)MmCreateHyperspaceMapping(PTE_TO_PFN(PageDirTable[i]));
+	    MmDeleteHyperspaceMapping(PageDirTable);
          }
          else
          {
@@ -2138,7 +2306,7 @@
    
       if (Process != NULL && Process != PsGetCurrentProcess())
       {
-         Pde = ExAllocatePageWithPhysPage(Process->Pcb.DirectoryTableBase.u.LowPart >> PAGE_SHIFT);
+         Pde = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase.u.LowPart));
       }
       else
       {
@@ -2153,22 +2321,26 @@
       }
       if (Pde != (PULONG)PAGEDIRECTORY_MAP)
       {
-         ExUnmapPage(Pde);
+         MmDeleteHyperspaceMapping(Pde);
       }
    }
 }
-	    
+
 VOID INIT_FUNCTION
 MmInitGlobalKernelPageDirectory(VOID)
 {
    ULONG i;
+
+   DPRINT("MmInitGlobalKernelPageDirectory()\n");
+
    if (Ke386Pae)
    {
       PULONGLONG CurrentPageDirectory = (PULONGLONG)PAE_PAGEDIRECTORY_MAP;
       for (i = PAE_ADDR_TO_PDE_OFFSET(KERNEL_BASE); i < 4 * 512; i++)
       {
-         if ((i < PAE_ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) || i >= PAE_ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) + 4) &&
-             0LL == MmGlobalKernelPageDirectoryForPAE[i] && 0LL != CurrentPageDirectory[i])
+         if (!(i >= PAE_ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) && i < PAE_ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) + 4) &&
+	     !(i >= PAE_ADDR_TO_PDE_OFFSET(HYPERSPACE) && i < PAE_ADDR_TO_PDE_OFFSET(HYPERSPACE) + 2) &&
+	     0LL == MmGlobalKernelPageDirectoryForPAE[i] && 0LL != CurrentPageDirectory[i])
          {
             ExfpInterlockedExchange64UL(&MmGlobalKernelPageDirectoryForPAE[i], &CurrentPageDirectory[i]);
 	    if (Ke386GlobalPagesEnabled)
@@ -2185,6 +2357,7 @@
       for (i = ADDR_TO_PDE_OFFSET(KERNEL_BASE); i < 1024; i++)
       {
          if (i != ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) &&
+	     i != ADDR_TO_PDE_OFFSET(HYPERSPACE) &&
              0 == MmGlobalKernelPageDirectory[i] && 0 != CurrentPageDirectory[i])
          {
             MmGlobalKernelPageDirectory[i] = CurrentPageDirectory[i];
@@ -2218,22 +2391,26 @@
       memcpy(PageDirTable, (PVOID)PAGEDIRECTORY_MAP, PAGE_SIZE);
 
       PageDir = (PULONGLONG)*LastKernelAddress;
-      (*LastKernelAddress) += 4 * PAGE_SIZE;
+      (*LastKernelAddress) += 6 * PAGE_SIZE;
       PageDirTable[0] = MmGetPhysicalAddress((PVOID)PageDir).QuadPart | PA_PRESENT;
       PageDirTable[1] = PageDirTable[0] + PAGE_SIZE;
       PageDirTable[2] = PageDirTable[1] + PAGE_SIZE;
       PageDirTable[3] = PageDirTable[2] + PAGE_SIZE;
 
-      memset(PageDir, 0, 4 * PAGE_SIZE);
+      memset(PageDir, 0, 6 * PAGE_SIZE);
 
       for (i = 0; i < 4; i++)
       {
-         PageDir[3*512+PAE_ADDR_TO_PDE_PAGE_OFFSET(PAGETABLE_MAP) + i] = PageDirTable[i] | PA_READWRITE;
+         PageDir[PAE_ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) + i] = PageDirTable[i] | PA_READWRITE;
       }
+      PageDir[PAE_ADDR_TO_PDE_OFFSET(HYPERSPACE)] = (PageDirTable[0] + 4 * PAGE_SIZE) | PA_READWRITE; 
+      PageDir[PAE_ADDR_TO_PDE_OFFSET(HYPERSPACE)+1] = (PageDirTable[0] + 5 * PAGE_SIZE) | PA_READWRITE; 
 
       for (i = 0; i < 2048; i++)
       {
-         if (i < PAE_ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) || i >= PAE_ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) + 4)
+         if (!(i >= PAE_ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) && i < PAE_ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) + 4) &&
+	     !(i >= PAE_ADDR_TO_PDE_OFFSET(HYPERSPACE) && i < PAE_ADDR_TO_PDE_OFFSET(HYPERSPACE)+2))
+	     
          {
             PVOID Address = (PVOID)(i * 512 * PAGE_SIZE);
 	    PULONG Pde = ADDR_TO_PDE(Address);
@@ -2293,9 +2470,12 @@
 MiInitPageDirectoryMap(VOID)
 {
    MEMORY_AREA* kernel_map_desc = NULL;
+   MEMORY_AREA* hyperspace_desc = NULL;
    PHYSICAL_ADDRESS BoundaryAddressMultiple;
    PVOID BaseAddress;
 
+   DPRINT("MiInitPageDirectoryMap()\n");
+
    BoundaryAddressMultiple.QuadPart = 0;
    BaseAddress = (PVOID)PAGETABLE_MAP;
    MmCreateMemoryArea(NULL,
@@ -2308,6 +2488,17 @@
                       TRUE,
                       FALSE,
                       BoundaryAddressMultiple);
+   BaseAddress = (PVOID)HYPERSPACE;
+   MmCreateMemoryArea(NULL,
+                      MmGetKernelAddressSpace(),
+                      MEMORY_AREA_SYSTEM,
+                      &BaseAddress,
+		      0x400000,
+                      0,
+                      &hyperspace_desc,
+                      TRUE,
+                      FALSE,
+                      BoundaryAddressMultiple);
 }
 
 /* EOF */

Modified: trunk/reactos/ntoskrnl/mm/kmap.c
--- trunk/reactos/ntoskrnl/mm/kmap.c	2005-01-25 22:36:28 UTC (rev 13287)
+++ trunk/reactos/ntoskrnl/mm/kmap.c	2005-01-25 22:50:47 UTC (rev 13288)
@@ -15,61 +15,19 @@
 
 /* GLOBALS *****************************************************************/
 
-#define ALLOC_MAP_SIZE (MM_KERNEL_MAP_SIZE / PAGE_SIZE)
-
-/*
- * One bit for each page in the kmalloc region
- *      If set then the page is used by a kmalloc block
- */
-static UCHAR AllocMapBuffer[ROUND_UP(ALLOC_MAP_SIZE, 32) / 8];
-static RTL_BITMAP AllocMap;
-static KSPIN_LOCK AllocMapLock;
-static ULONG AllocMapHint = 0;
-
 /* FUNCTIONS ***************************************************************/
-
-VOID
-ExUnmapPage(PVOID Addr)
-{
-   KIRQL oldIrql;
-   ULONG_PTR Base = ((ULONG_PTR)Addr - (ULONG_PTR)MM_KERNEL_MAP_BASE) / PAGE_SIZE;
-
-   DPRINT("ExUnmapPage(Addr %x)\n",Addr);
-
-   MmDeleteVirtualMapping(NULL, (PVOID)Addr, FALSE, NULL, NULL);
-   KeAcquireSpinLock(&AllocMapLock, &oldIrql);
-   RtlClearBits(&AllocMap, Base, 1);
-   AllocMapHint = min(AllocMapHint, Base);
-   KeReleaseSpinLock(&AllocMapLock, oldIrql);
-}
-
-PVOID
-ExAllocatePage(VOID)
-{
-   PFN_TYPE Page;
-   NTSTATUS Status;
-
-   Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Page);
-   if (!NT_SUCCESS(Status))
-   {
-      return(NULL);
-   }
-
-   return(ExAllocatePageWithPhysPage(Page));
-}
-
 NTSTATUS
 MiZeroPage(PFN_TYPE Page)
 {
    PVOID TempAddress;
 
-   TempAddress = ExAllocatePageWithPhysPage(Page);
+   TempAddress = MmCreateHyperspaceMapping(Page);
    if (TempAddress == NULL)
    {
       return(STATUS_NO_MEMORY);
    }
    memset(TempAddress, 0, PAGE_SIZE);
-   ExUnmapPage(TempAddress);
+   MmDeleteHyperspaceMapping(TempAddress);
    return(STATUS_SUCCESS);
 }
 
@@ -78,99 +36,13 @@
 {
    PVOID TempAddress;
 
-   TempAddress = ExAllocatePageWithPhysPage(DestPage);
+   TempAddress = MmCreateHyperspaceMapping(DestPage);
    if (TempAddress == NULL)
    {
       return(STATUS_NO_MEMORY);
    }
    memcpy(TempAddress, SourceAddress, PAGE_SIZE);
-   ExUnmapPage(TempAddress);
+   MmDeleteHyperspaceMapping(TempAddress);
    return(STATUS_SUCCESS);
 }
 
-PVOID
-ExAllocatePageWithPhysPage(PFN_TYPE Page)
-{
-   KIRQL oldlvl;
-   PVOID Addr;
-   ULONG_PTR Base;
-   NTSTATUS Status;
-
-   KeAcquireSpinLock(&AllocMapLock, &oldlvl);
-   Base = RtlFindClearBitsAndSet(&AllocMap, 1, AllocMapHint);
-   if (Base != (ULONG_PTR)-1)
-   {
-      AllocMapHint = Base + 1;
-      KeReleaseSpinLock(&AllocMapLock, oldlvl);
-      Addr = (char*)MM_KERNEL_MAP_BASE + Base * PAGE_SIZE;
-      Status = MmCreateVirtualMapping(NULL,
-                                      Addr,
-                                      PAGE_READWRITE | PAGE_SYSTEM,
-                                      &Page,
-                                      1);
-      if (!NT_SUCCESS(Status))
-      {
-         DbgPrint("Unable to create virtual mapping\n");
-         KEBUGCHECK(0);
-      }
-      return Addr;
-   }
-   KeReleaseSpinLock(&AllocMapLock, oldlvl);
-   return NULL;
-}
-
-VOID INIT_FUNCTION
-MiInitKernelMap(VOID)
-{
-   KeInitializeSpinLock(&AllocMapLock);
-   RtlInitializeBitMap(&AllocMap, (PULONG)AllocMapBuffer, ALLOC_MAP_SIZE);
-   RtlClearAllBits(&AllocMap);
-}
-
-VOID
-MiFreeNonPagedPoolRegion(PVOID Addr, ULONG Count, BOOLEAN Free)
-{
-   ULONG i;
-   ULONG_PTR Base = ((char*)Addr - (char*)MM_KERNEL_MAP_BASE) / PAGE_SIZE;
-   KIRQL oldlvl;
-
-   for (i = 0; i < Count; i++)
-   {
-      MmDeleteVirtualMapping(NULL,
-                             (char*)Addr + (i * PAGE_SIZE),
-                             Free,
-                             NULL,
-                             NULL);
-   }
-   KeAcquireSpinLock(&AllocMapLock, &oldlvl);
-   RtlClearBits(&AllocMap, Base, Count);
-   AllocMapHint = min(AllocMapHint, Base);
-   KeReleaseSpinLock(&AllocMapLock, oldlvl);
-}
-
-PVOID
-MiAllocNonPagedPoolRegion(ULONG nr_pages)
-/*
- * FUNCTION: Allocates a region of pages within the nonpaged pool area
- */
-{
-   ULONG_PTR Base;
-   KIRQL oldlvl;
-
-   KeAcquireSpinLock(&AllocMapLock, &oldlvl);
-   Base = RtlFindClearBitsAndSet(&AllocMap, nr_pages, AllocMapHint);
-   if (Base == (ULONG_PTR)-1)
-   {
-      DbgPrint("CRITICAL: Out of non-paged pool space\n");
-      KEBUGCHECK(0);
-   }
-   if (AllocMapHint == Base)
-   {
-      AllocMapHint += nr_pages;
-   }
-   KeReleaseSpinLock(&AllocMapLock, oldlvl);
[truncated at 1000 lines; 81 more skipped]