#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
+#include "../ARM3/miarm.h"
#if defined (ALLOC_PRAGMA)
#pragma alloc_text(INIT, MmInitGlobalKernelPageDirectory)
}
#endif
+const
+ULONG
+MmProtectToPteMask[32] =
+{
+ //
+ // These are the base MM_ protection flags
+ //
+ 0,
+ PTE_READONLY | PTE_ENABLE_CACHE,
+ PTE_EXECUTE | PTE_ENABLE_CACHE,
+ PTE_EXECUTE_READ | PTE_ENABLE_CACHE,
+ PTE_READWRITE | PTE_ENABLE_CACHE,
+ PTE_WRITECOPY | PTE_ENABLE_CACHE,
+ PTE_EXECUTE_READWRITE | PTE_ENABLE_CACHE,
+ PTE_EXECUTE_WRITECOPY | PTE_ENABLE_CACHE,
+ //
+ // These OR in the MM_NOCACHE flag
+ //
+ 0,
+ PTE_READONLY | PTE_DISABLE_CACHE,
+ PTE_EXECUTE | PTE_DISABLE_CACHE,
+ PTE_EXECUTE_READ | PTE_DISABLE_CACHE,
+ PTE_READWRITE | PTE_DISABLE_CACHE,
+ PTE_WRITECOPY | PTE_DISABLE_CACHE,
+ PTE_EXECUTE_READWRITE | PTE_DISABLE_CACHE,
+ PTE_EXECUTE_WRITECOPY | PTE_DISABLE_CACHE,
+ //
+ // These OR in the MM_DECOMMIT flag, which doesn't seem supported on x86/64/ARM
+ //
+ 0,
+ PTE_READONLY | PTE_ENABLE_CACHE,
+ PTE_EXECUTE | PTE_ENABLE_CACHE,
+ PTE_EXECUTE_READ | PTE_ENABLE_CACHE,
+ PTE_READWRITE | PTE_ENABLE_CACHE,
+ PTE_WRITECOPY | PTE_ENABLE_CACHE,
+ PTE_EXECUTE_READWRITE | PTE_ENABLE_CACHE,
+ PTE_EXECUTE_WRITECOPY | PTE_ENABLE_CACHE,
+ //
+ // These OR in the MM_NOACCESS flag, which seems to enable WriteCombining?
+ //
+ 0,
+ PTE_READONLY | PTE_WRITECOMBINED_CACHE,
+ PTE_EXECUTE | PTE_WRITECOMBINED_CACHE,
+ PTE_EXECUTE_READ | PTE_WRITECOMBINED_CACHE,
+ PTE_READWRITE | PTE_WRITECOMBINED_CACHE,
+ PTE_WRITECOPY | PTE_WRITECOMBINED_CACHE,
+ PTE_EXECUTE_READWRITE | PTE_WRITECOMBINED_CACHE,
+ PTE_EXECUTE_WRITECOPY | PTE_WRITECOMBINED_CACHE,
+};
+
+const
+ULONG MmProtectToValue[32] =
+{
+ PAGE_NOACCESS,
+ PAGE_READONLY,
+ PAGE_EXECUTE,
+ PAGE_EXECUTE_READ,
+ PAGE_READWRITE,
+ PAGE_WRITECOPY,
+ PAGE_EXECUTE_READWRITE,
+ PAGE_EXECUTE_WRITECOPY,
+ PAGE_NOACCESS,
+ PAGE_NOCACHE | PAGE_READONLY,
+ PAGE_NOCACHE | PAGE_EXECUTE,
+ PAGE_NOCACHE | PAGE_EXECUTE_READ,
+ PAGE_NOCACHE | PAGE_READWRITE,
+ PAGE_NOCACHE | PAGE_WRITECOPY,
+ PAGE_NOCACHE | PAGE_EXECUTE_READWRITE,
+ PAGE_NOCACHE | PAGE_EXECUTE_WRITECOPY,
+ PAGE_NOACCESS,
+ PAGE_GUARD | PAGE_READONLY,
+ PAGE_GUARD | PAGE_EXECUTE,
+ PAGE_GUARD | PAGE_EXECUTE_READ,
+ PAGE_GUARD | PAGE_READWRITE,
+ PAGE_GUARD | PAGE_WRITECOPY,
+ PAGE_GUARD | PAGE_EXECUTE_READWRITE,
+ PAGE_GUARD | PAGE_EXECUTE_WRITECOPY,
+ PAGE_NOACCESS,
+ PAGE_WRITECOMBINE | PAGE_READONLY,
+ PAGE_WRITECOMBINE | PAGE_EXECUTE,
+ PAGE_WRITECOMBINE | PAGE_EXECUTE_READ,
+ PAGE_WRITECOMBINE | PAGE_READWRITE,
+ PAGE_WRITECOMBINE | PAGE_WRITECOPY,
+ PAGE_WRITECOMBINE | PAGE_EXECUTE_READWRITE,
+ PAGE_WRITECOMBINE | PAGE_EXECUTE_WRITECOPY
+};
+
/* FUNCTIONS ***************************************************************/
BOOLEAN MmUnmapPageTable(PULONG Pt);
return(Attributes);
}
-NTSTATUS
-NTAPI
-Mmi386ReleaseMmInfo(PEPROCESS Process)
-{
- PUSHORT LdtDescriptor;
- ULONG LdtBase;
- PULONG PageDir;
- ULONG i;
-
- DPRINT("Mmi386ReleaseMmInfo(Process %x)\n",Process);
-
- LdtDescriptor = (PUSHORT) &Process->Pcb.LdtDescriptor;
- LdtBase = LdtDescriptor[1] |
- ((LdtDescriptor[2] & 0xff) << 16) |
- ((LdtDescriptor[3] & ~0xff) << 16);
-
- DPRINT("LdtBase: %x\n", LdtBase);
-
- if (LdtBase)
- {
- ExFreePool((PVOID) LdtBase);
- }
-
- PageDir = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0]));
- for (i = 0; i < ADDR_TO_PDE_OFFSET(MmSystemRangeStart); i++)
- {
- if (PageDir[i] != 0)
- {
- MiZeroPage(PTE_TO_PFN(PageDir[i]));
- MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PFN(PageDir[i]));
- }
- }
- MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PFN(PageDir[ADDR_TO_PDE_OFFSET(HYPERSPACE)]));
- MmDeleteHyperspaceMapping(PageDir);
- MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0]));
-
- Process->Pcb.DirectoryTableBase[0] = 0;
- Process->Pcb.DirectoryTableBase[1] = 0;
-
- DPRINT("Finished Mmi386ReleaseMmInfo()\n");
- return(STATUS_SUCCESS);
-}
-
-NTSTATUS
-NTAPI
-MmInitializeHandBuiltProcess(IN PEPROCESS Process,
- IN PULONG DirectoryTableBase)
-{
- /* Share the directory base with the idle process */
- DirectoryTableBase[0] = PsGetCurrentProcess()->Pcb.DirectoryTableBase[0];
- DirectoryTableBase[1] = PsGetCurrentProcess()->Pcb.DirectoryTableBase[1];
-
- /* Initialize the Addresss Space */
- KeInitializeGuardedMutex(&Process->AddressCreationLock);
- Process->Vm.WorkingSetExpansionLinks.Flink = NULL;
- ASSERT(Process->VadRoot.NumberGenericTableElements == 0);
- Process->VadRoot.BalancedRoot.u1.Parent = &Process->VadRoot.BalancedRoot;
-
- /* The process now has an address space */
- Process->HasAddressSpace = TRUE;
- return STATUS_SUCCESS;
-}
-
-BOOLEAN
-NTAPI
-MmCreateProcessAddressSpace(IN ULONG MinWs,
- IN PEPROCESS Process,
- IN PULONG DirectoryTableBase)
-{
- NTSTATUS Status;
- ULONG i, j;
- PFN_TYPE Pfn[2];
- PULONG PageDirectory;
-
- DPRINT("MmCopyMmInfo(Src %x, Dest %x)\n", MinWs, Process);
-
- for (i = 0; i < 2; i++)
- {
- Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn[i]);
- if (!NT_SUCCESS(Status))
- {
- for (j = 0; j < i; j++)
- {
- MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn[j]);
- }
-
- return FALSE;
- }
- }
-
- PageDirectory = MmCreateHyperspaceMapping(Pfn[0]);
-
- memcpy(PageDirectory + ADDR_TO_PDE_OFFSET(MmSystemRangeStart),
- MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(MmSystemRangeStart),
- (1024 - ADDR_TO_PDE_OFFSET(MmSystemRangeStart)) * sizeof(ULONG));
-
- 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;
-
- MmDeleteHyperspaceMapping(PageDirectory);
-
- DirectoryTableBase[0] = PFN_TO_PTE(Pfn[0]);
- DirectoryTableBase[1] = 0;
- DPRINT("Finished MmCopyMmInfo(): 0x%x\n", DirectoryTableBase[0]);
- return TRUE;
-}
-
static PULONG
MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
{
ULONG PdeOffset = ADDR_TO_PDE_OFFSET(Address);
NTSTATUS Status;
- PFN_TYPE Pfn;
+ PFN_NUMBER Pfn;
ULONG Entry;
PULONG Pt, PageDir;
MmDeleteHyperspaceMapping(PageDir);
return NULL;
}
- Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
+ 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 = InterlockedCompareExchangePte(&PageDir[PdeOffset], PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE | PA_USER, 0);
if (Entry != 0)
{
- MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
+ MmReleasePageMemoryConsumer(MC_SYSTEM, Pfn);
Pfn = PTE_TO_PFN(Entry);
}
}
{
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)
{
{
return NULL;
}
- Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
+ 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 = InterlockedCompareExchangePte(PageDir, PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE | PA_USER, 0);
if (Entry != 0)
{
- MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
+ MmReleasePageMemoryConsumer(MC_SYSTEM, Pfn);
}
}
}
return 0;
}
-PFN_TYPE
+PFN_NUMBER
NTAPI
MmGetPfnForProcess(PEPROCESS Process,
PVOID Address)
VOID
NTAPI
-MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN* WasDirty, PPFN_TYPE Page)
+MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN* WasDirty, PPFN_NUMBER Page)
/*
* FUNCTION: Delete a virtual mapping
*/
VOID
NTAPI
MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN FreePage,
- BOOLEAN* WasDirty, PPFN_TYPE Page)
+ BOOLEAN* WasDirty, PPFN_NUMBER Page)
/*
* FUNCTION: Delete a virtual mapping
*/
{
BOOLEAN WasValid = FALSE;
- PFN_TYPE Pfn;
+ PFN_NUMBER Pfn;
ULONG Pte;
PULONG Pt;
if (FreePage && WasValid)
{
- MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
+ MmReleasePageMemoryConsumer(MC_SYSTEM, Pfn);
}
/*
}
}
+VOID
+NTAPI
+MmGetPageFileMapping(PEPROCESS Process, PVOID Address,
+ SWAPENTRY* SwapEntry)
+/*
+ * FUNCTION: Get a page file mapping
+ */
+{
+ ULONG Entry = MmGetPageEntryForProcess(Process, Address);
+ *SwapEntry = Entry >> 1;
+}
+
VOID
NTAPI
MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
MmCreateVirtualMappingUnsafe(PEPROCESS Process,
PVOID Address,
ULONG flProtect,
- PPFN_TYPE Pages,
+ PPFN_NUMBER Pages,
ULONG PageCount)
{
ULONG Attributes;
ULONG oldPdeOffset, PdeOffset;
PULONG Pt = NULL;
ULONG Pte;
- BOOLEAN NoExecute = FALSE;
-
DPRINT("MmCreateVirtualMappingUnsafe(%x, %x, %x, %x (%x), %d)\n",
Process, Address, flProtect, Pages, *Pages, PageCount);
}
Attributes = ProtectToPTE(flProtect);
- if (Attributes & 0x80000000)
- {
- NoExecute = TRUE;
- }
Attributes &= 0xfff;
if (Address >= MmSystemRangeStart)
{
MmCreateVirtualMapping(PEPROCESS Process,
PVOID Address,
ULONG flProtect,
- PPFN_TYPE Pages,
+ PPFN_NUMBER Pages,
ULONG PageCount)
{
ULONG i;
MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
{
ULONG Attributes = 0;
- BOOLEAN NoExecute = FALSE;
PULONG Pt;
DPRINT("MmSetPageProtect(Process %x Address %x flProtect %x)\n",
Attributes = ProtectToPTE(flProtect);
- if (Attributes & 0x80000000)
- {
- NoExecute = TRUE;
- }
Attributes &= 0xfff;
if (Address >= MmSystemRangeStart)
{
return p;
}
-VOID
-NTAPI
-MmUpdatePageDir(PEPROCESS Process, PVOID Address, ULONG Size)
-{
- ULONG StartOffset, EndOffset, Offset;
- PULONG Pde;
-
- //
- // Check if the process isn't there anymore
- // This is probably a bad sign, since it means the caller is setting cr3 to
- // 0 or something...
- //
- if ((PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0]) == 0) && (Process != PsGetCurrentProcess()))
- {
- DPRINT1("Process: %16s is dead: %p\n", Process->ImageFileName, Process->Pcb.DirectoryTableBase[0]);
- ASSERT(FALSE);
- return;
- }
-
- if (Address < MmSystemRangeStart)
- {
- KeBugCheck(MEMORY_MANAGEMENT);
- }
-
- StartOffset = ADDR_TO_PDE_OFFSET(Address);
- EndOffset = ADDR_TO_PDE_OFFSET((PVOID)((ULONG_PTR)Address + Size));
-
- if (Process != NULL && Process != PsGetCurrentProcess())
- {
- Pde = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0]));
- }
- else
- {
- Pde = (PULONG)PAGEDIRECTORY_MAP;
- }
- for (Offset = StartOffset; Offset <= EndOffset; Offset++)
- {
- if (Offset != ADDR_TO_PDE_OFFSET(PAGETABLE_MAP))
- {
- InterlockedCompareExchangePte(&Pde[Offset], MmGlobalKernelPageDirectory[Offset], 0);
- }
- }
- if (Pde != (PULONG)PAGEDIRECTORY_MAP)
- {
- MmDeleteHyperspaceMapping(Pde);
- }
-}
-
VOID
INIT_FUNCTION
NTAPI