else
{
DPRINT1("Unknown main protection type.\n");
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
if (!(flProtect & PAGE_SYSTEM))
{
#define ADDR_TO_PAGE_TABLE(v) (((ULONG)(v)) / (4 * 1024 * 1024))
#define ADDR_TO_PDE(v) (PULONG)(PAGEDIRECTORY_MAP + \
- (((ULONG)v / (1024 * 1024))&(~0x3)))
+ ((((ULONG)(v)) / (1024 * 1024))&(~0x3)))
#define ADDR_TO_PTE(v) (PULONG)(PAGETABLE_MAP + ((((ULONG)v / 1024))&(~0x3)))
-#define ADDR_TO_PDE_OFFSET(v) (((ULONG)v / (4 * 1024 * 1024)))
+#define ADDR_TO_PDE_OFFSET(v) ((((ULONG)(v)) / (4 * 1024 * 1024)))
NTSTATUS Mmi386ReleaseMmInfo(PEPROCESS Process)
{
+ PUSHORT LdtDescriptor;
+ ULONG LdtBase;
+
DPRINT("Mmi386ReleaseMmInfo(Process %x)\n",Process);
+
+ LdtDescriptor = (PUSHORT) &Process->Pcb.LdtDescriptor[0];
+ LdtBase = LdtDescriptor[1] |
+ ((LdtDescriptor[2] & 0xff) << 16) |
+ ((LdtDescriptor[3] & ~0xff) << 16);
+
+ DPRINT("LdtBase: %x\n", LdtBase);
+
+ if (LdtBase)
+ {
+ ExFreePool((PVOID) LdtBase);
+ }
MmReleasePageMemoryConsumer(MC_NPPOOL, Process->Pcb.DirectoryTableBase);
Process->Pcb.DirectoryTableBase.QuadPart = 0LL;
{
PHYSICAL_ADDRESS PhysPageDirectory;
PULONG PageDirectory;
- PULONG CurrentPageDirectory;
PKPROCESS KProcess = &Dest->Pcb;
- ULONG i;
DPRINT("MmCopyMmInfo(Src %x, Dest %x)\n", Src, Dest);
}
PhysPageDirectory = MmGetPhysicalAddress(PageDirectory);
KProcess->DirectoryTableBase = PhysPageDirectory;
- CurrentPageDirectory = (PULONG)PAGEDIRECTORY_MAP;
- memset(PageDirectory,0,PAGE_SIZE);
- for (i=768; i<896; i++)
- {
- PageDirectory[i] = CurrentPageDirectory[i];
- }
- for (i=961; i<1024; i++)
- {
- PageDirectory[i] = CurrentPageDirectory[i];
- }
+ memset(PageDirectory,0, ADDR_TO_PDE_OFFSET(KERNEL_BASE) * sizeof(ULONG));
+ 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;
*(ADDR_TO_PDE(Address)) = 0;
if (Address >= (PVOID)KERNEL_BASE)
{
- KeBugCheck(0);
+ KEBUGCHECK(0);
// MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0;
}
FLUSH_TLB;
{
DbgPrint("Page table entry not clear at %x/%x (is %x)\n",
((ULONG)Address / 4*1024*1024), i, PageTable[i]);
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
}
npage = *(ADDR_TO_PDE(Address));
if (Address >= (PVOID)KERNEL_BASE)
{
// MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0;
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
else
{
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, MayWait, &npage);
if (!NT_SUCCESS(Status))
{
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
oldIrql = KeRaiseIrqlToSynchLevel();
/* An other thread can set this pde entry, we must check again */
}
if ((*Pde) == 0)
{
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
/*
WasValid = (PAGE_MASK(Pte) != 0);
if (!WasValid)
{
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
/*
}
VOID
+MmRawDeleteVirtualMapping(PVOID Address)
+{
+ PULONG Pde, kePde;
+
+ /*
+ * Set the page directory entry, we may have to copy the entry from
+ * the global page directory.
+ */
+ Pde = ADDR_TO_PDE(Address);
+ if (*Pde == 0 && Address >= (PVOID)KERNEL_BASE)
+ {
+ kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(Address);
+ if (*kePde != 0)
+ {
+ *Pde = *kePde;
+ FLUSH_TLB;
+ }
+ }
+
+ if (*Pde == 0)
+ {
+ return;
+ }
+
+ /*
+ * Set the entry to zero
+ */
+ *ADDR_TO_PTE(Address) = 0;
+ FLUSH_TLB;
+}
+
+VOID
MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage,
BOOL* WasDirty, PHYSICAL_ADDRESS* PhysicalAddr)
/*
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &npage);
if (!NT_SUCCESS(Status))
{
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
MiZeroPage(npage);
oldIrql = KeRaiseIrqlToSynchLevel();
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &npage);
if (!NT_SUCCESS(Status))
{
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
MiZeroPage(npage);
*Pde = npage.u.LowPart | PA_PRESENT | PA_READWRITE | PA_USER;
MmIsAccessedAndResetAccessPage(PEPROCESS Process, PVOID Address)
{
PULONG PageEntry;
- PEPROCESS CurrentProcess = PsGetCurrentProcess();
+ PEPROCESS CurrentProcess;
BOOLEAN Accessed;
- if (Process != CurrentProcess)
+ if (Process)
{
- KeAttachProcess(Process);
+ CurrentProcess = PsGetCurrentProcess();
+ if (Process != CurrentProcess)
+ {
+ KeAttachProcess(Process);
+ }
}
+ else
+ {
+ if (((ULONG)Address & ~0xFFF) < KERNEL_BASE)
+ {
+ DPRINT1("MmIsAccessedAndResetAccessPage is called for user space without a process.\n");
+ KEBUGCHECK(0);
+ }
+ CurrentProcess = NULL;
+ }
+
PageEntry = MmGetPageEntry(Address);
Accessed = (*PageEntry) & PA_ACCESSED;
if (Accessed)
VOID MmSetCleanPage(PEPROCESS Process, PVOID Address)
{
PULONG PageEntry;
- PEPROCESS CurrentProcess = PsGetCurrentProcess();
-
- if (Process != CurrentProcess)
+ PEPROCESS CurrentProcess;
+
+ if (Process)
{
- KeAttachProcess(Process);
+ CurrentProcess = PsGetCurrentProcess();
+ if (Process != CurrentProcess)
+ {
+ KeAttachProcess(Process);
+ }
+ }
+ else
+ {
+ if (((ULONG)Address & ~0xFFF) < KERNEL_BASE)
+ {
+ DPRINT1("MmSetCleanPage is called for user space without a process.\n");
+ KEBUGCHECK(0);
+ }
+ CurrentProcess = NULL;
}
PageEntry = MmGetPageEntry(Address);
(*PageEntry) = (*PageEntry) & (~PA_DIRTY);
VOID MmSetDirtyPage(PEPROCESS Process, PVOID Address)
{
PULONG PageEntry;
- PEPROCESS CurrentProcess = PsGetCurrentProcess();
-
- if (Process != CurrentProcess)
+ PEPROCESS CurrentProcess = NULL;
+
+ if (Process)
{
- KeAttachProcess(Process);
+ CurrentProcess = PsGetCurrentProcess();
+ if (Process != CurrentProcess)
+ {
+ KeAttachProcess(Process);
+ }
+ }
+ else
+ {
+ if (((ULONG)Address & ~0xFFF) < KERNEL_BASE)
+ {
+ DPRINT1("MmSetDirtyPage is called for user space without a process.\n");
+ KEBUGCHECK(0);
+ }
+ CurrentProcess = NULL;
}
PageEntry = MmGetPageEntry(Address);
(*PageEntry) = (*PageEntry) | PA_DIRTY;
}
NTSTATUS
+MmCreateVirtualMappingDump(PVOID Address,
+ ULONG flProtect,
+ PHYSICAL_ADDRESS PhysicalAddress)
+{
+ ULONG Attributes;
+ PULONG Pte;
+ NTSTATUS Status;
+
+ if (Address < (PVOID)KERNEL_BASE)
+ {
+ DPRINT1("No process\n");
+ KEBUGCHECK(0);
+ }
+
+ Attributes = ProtectToPTE(flProtect);
+ if (!(Attributes & PA_PRESENT) && PhysicalAddress.QuadPart != 0)
+ {
+ DPRINT1("Setting physical address but not allowing access at address "
+ "0x%.8X with attributes %x/%x.\n",
+ Address, Attributes, flProtect);
+ KEBUGCHECK(0);
+ }
+
+ Status = MmGetPageEntry2(Address, &Pte, FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ return(Status);
+ }
+ if (PAGE_MASK((*Pte)) != 0 && !((*Pte) & PA_PRESENT))
+ {
+ KEBUGCHECK(0);
+ }
+ *Pte = PhysicalAddress.QuadPart | Attributes;
+ FLUSH_TLB;
+ return(STATUS_SUCCESS);
+}
+
+
+NTSTATUS
MmCreateVirtualMappingForKernel(PVOID Address,
ULONG flProtect,
PHYSICAL_ADDRESS PhysicalAddress)
if (Process == NULL && Address < (PVOID)KERNEL_BASE)
{
DPRINT1("No process\n");
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
if (Process != NULL && Address >= (PVOID)KERNEL_BASE)
{
DPRINT1("Setting kernel address with process context\n");
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
Attributes = ProtectToPTE(flProtect);
}
if (PAGE_MASK((*Pte)) != 0 && !((*Pte) & PA_PRESENT))
{
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
if (PAGE_MASK((*Pte)) != 0)
{
*Pte = PhysicalAddress.QuadPart | Attributes;
if (Process != NULL &&
Process->AddressSpace.PageTableRefCountTable != NULL &&
- ADDR_TO_PAGE_TABLE(Address) < 768 &&
+ Address < (PVOID)KERNEL_BASE &&
Attributes & PA_PRESENT)
{
PUSHORT Ptrc;
if (Process == NULL && Address < (PVOID)KERNEL_BASE)
{
DPRINT1("No process\n");
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
if (Process != NULL && Address >= (PVOID)KERNEL_BASE)
{
DPRINT1("Setting kernel address with process context\n");
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
if (SwapEntry & (1 << 31))
{
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
if (Process != NULL && Process != CurrentProcess)
*Pte = SwapEntry << 1;
if (Process != NULL &&
Process->AddressSpace.PageTableRefCountTable != NULL &&
- ADDR_TO_PAGE_TABLE(Address) < 768)
+ Address < (PVOID)KERNEL_BASE)
{
PUSHORT Ptrc;
return(STATUS_SUCCESS);
}
+
+
NTSTATUS
MmCreateVirtualMappingUnsafe(PEPROCESS Process,
PVOID Address,
if (Process == NULL && Address < (PVOID)KERNEL_BASE)
{
DPRINT1("No process\n");
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
if (Process != NULL && Address >= (PVOID)KERNEL_BASE)
{
DPRINT1("Setting kernel address with process context\n");
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
MmMarkPageMapped(PhysicalAddress);
DPRINT1("Setting physical address but not allowing access at address "
"0x%.8X with attributes %x/%x.\n",
Address, Attributes, flProtect);
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
if (Process != NULL && Process != CurrentProcess)
}
if (PAGE_MASK((*Pte)) != 0 && !((*Pte) & PA_PRESENT))
{
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
if (PAGE_MASK((*Pte)) != 0)
{
*Pte = PhysicalAddress.QuadPart | Attributes;
if (Process != NULL &&
Process->AddressSpace.PageTableRefCountTable != NULL &&
- ADDR_TO_PAGE_TABLE(Address) < 768 &&
+ Address < (PVOID)KERNEL_BASE &&
Attributes & PA_PRESENT)
{
PUSHORT Ptrc;
if (!MmIsUsablePage(PhysicalAddress))
{
DPRINT1("Page at address %x not usable\n", PhysicalAddress);
- KeBugCheck(0);
+ KEBUGCHECK(0);
}
return(MmCreateVirtualMappingUnsafe(Process,
}
}
+/*
+ * @implemented
+ */
PHYSICAL_ADDRESS STDCALL
MmGetPhysicalAddress(PVOID vaddr)
/*
}
+VOID
+MmUpdateStackPageDir(PULONG LocalPageDir, PKTHREAD PThread)
+{
+ unsigned EntryBase = ADDR_TO_PDE_OFFSET(PThread->StackLimit);
+ unsigned EntryTop = ADDR_TO_PDE_OFFSET(PThread->InitialStack - PAGE_SIZE);
+
+ if (0 == LocalPageDir[EntryBase])
+ {
+ LocalPageDir[EntryBase] = MmGlobalKernelPageDirectory[EntryBase];
+ }
+ if (EntryBase != EntryTop && 0 == LocalPageDir[EntryTop])
+ {
+ LocalPageDir[EntryTop] = MmGlobalKernelPageDirectory[EntryTop];
+ }
+}
+
+VOID
+MmInitGlobalKernelPageDirectory(VOID)
+{
+ ULONG i;
+ PULONG CurrentPageDirectory = (PULONG)PAGEDIRECTORY_MAP;
+
+ for (i = ADDR_TO_PDE_OFFSET(KERNEL_BASE); i < 1024; i++)
+ {
+ if (i != ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) &&
+ 0 == MmGlobalKernelPageDirectory[i] && 0 != CurrentPageDirectory[i])
+ {
+ MmGlobalKernelPageDirectory[i] = CurrentPageDirectory[i];
+ }
+ }
+}
+
/* EOF */