- 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.Q
uadPart >> PAGE_SHIFT);
+ PageDirTable =
(PULONGLONG)MmCreateHyperspaceMapping(PAE_PTE_TO_PFN(Process->Pcb.Direct
oryTableBase.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.L
owPart));
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_O
FFSET(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.Qua
dPart));
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.L
owPart));
}
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]