[NTOS:MM:X64] Simplify and fix x64 mapping code

- Use demand-zero-ptes in MiGetPteForProcess
- Handle NoExecute in MiSetPteProtection
- Fix MmIsPageSwapEntry
- Fix MmGetPageFileMapping
- remove obsolete functions.
This commit is contained in:
Timo Kreuzer 2018-02-04 13:33:14 +01:00
parent 0726cfce10
commit 8980850d56

View file

@ -144,75 +144,65 @@ MiGetPteForProcess(
PVOID Address,
BOOLEAN Create)
{
MMPTE TmplPte, *Pte;
PMMPTE Pte;
PMMPDE Pde;
PMMPPE Ppe;
PMMPXE Pxe;
/* Check if we need hypersapce mapping */
if (Address < MmSystemRangeStart &&
Process && Process != PsGetCurrentProcess())
/* Make sure the process is correct */
if (Address < MmSystemRangeStart)
{
UNIMPLEMENTED;
__debugbreak();
return NULL;
}
else if (Create)
{
KIRQL OldIrql;
TmplPte.u.Long = 0;
TmplPte.u.Flush.Valid = 1;
TmplPte.u.Flush.Write = 1;
/* All page table levels of user pages are user owned */
TmplPte.u.Flush.Owner = (Address < MmHighestUserAddress) ? 1 : 0;
/* Lock the PFN database */
OldIrql = MiAcquirePfnLock();
/* Get the PXE */
Pte = MiAddressToPxe(Address);
if (!Pte->u.Hard.Valid)
{
TmplPte.u.Hard.PageFrameNumber = MiRemoveZeroPage(0);
MI_WRITE_VALID_PTE(Pte, TmplPte);
}
/* Get the PPE */
Pte = MiAddressToPpe(Address);
if (!Pte->u.Hard.Valid)
{
TmplPte.u.Hard.PageFrameNumber = MiRemoveZeroPage(1);
MI_WRITE_VALID_PTE(Pte, TmplPte);
}
/* Get the PDE */
Pte = MiAddressToPde(Address);
if (!Pte->u.Hard.Valid)
{
TmplPte.u.Hard.PageFrameNumber = MiRemoveZeroPage(2);
MI_WRITE_VALID_PTE(Pte, TmplPte);
}
/* Unlock PFN database */
MiReleasePfnLock(OldIrql);
ASSERT(Process == PsGetCurrentProcess());
}
else
{
/* Get the PXE */
Pte = MiAddressToPxe(Address);
if (!Pte->u.Hard.Valid)
ASSERT((Process == NULL) || (Process == PsGetCurrentProcess()));
}
Pxe = MiAddressToPxe(Address);
Ppe = MiAddressToPpe(Address);
Pde = MiAddressToPde(Address);
Pte = MiAddressToPte(Address);
if (Create)
{
/* Check the PXE */
if (Pxe->u.Long == 0)
{
/* Make it demand zero */
MI_WRITE_INVALID_PDE(Pxe, DemandZeroPde);
}
/* Check the PPE */
if (Ppe->u.Long == 0)
{
/* Make it demand zero */
MI_WRITE_INVALID_PDE(Ppe, DemandZeroPde);
}
/* Check the PDE */
if (Pde->u.Long == 0)
{
/* Make it demand zero */
MI_WRITE_INVALID_PDE(Pde, DemandZeroPde);
}
}
else
{
/* Check the PXE */
if (!Pxe->u.Hard.Valid)
return NULL;
/* Get the PPE */
Pte = MiAddressToPpe(Address);
if (!Pte->u.Hard.Valid)
/* Check the PPE */
if (!Ppe->u.Hard.Valid)
return NULL;
/* Get the PDE */
Pte = MiAddressToPde(Address);
if (!Pte->u.Hard.Valid)
/* Check the PDE */
if (!Pde->u.Hard.Valid)
return NULL;
}
return MiAddressToPte(Address);
return Pte;
}
static
@ -272,8 +262,8 @@ MiGetPteProtection(MMPTE Pte)
return Protect;
}
static
VOID
NTAPI
MiSetPteProtection(PMMPTE Pte, ULONG Protection)
{
Pte->u.Flush.CopyOnWrite = (Protection & PAGE_WRITECOPY_ANY) ? 1 : 0;
@ -282,7 +272,7 @@ MiSetPteProtection(PMMPTE Pte, ULONG Protection)
Pte->u.Flush.WriteThrough = (Protection & PAGE_WRITETHROUGH) ? 1 : 0;
// FIXME: This doesn't work. Why?
// Pte->u.Flush.NoExecute = (Protection & PAGE_EXECUTE_ANY) ? 0 : 1;
Pte->u.Flush.NoExecute = (Protection & PAGE_EXECUTE_ANY) ? 0 : 1;
}
/* FUNCTIONS ***************************************************************/
@ -324,34 +314,7 @@ MmIsPageSwapEntry(PEPROCESS Process, PVOID Address)
{
MMPTE Pte;
Pte.u.Long = MiGetPteValueForProcess(Process, Address);
return Pte.u.Hard.Valid && Pte.u.Soft.Transition;
}
static PMMPTE
MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
{
__debugbreak();
return 0;
}
BOOLEAN MmUnmapPageTable(PMMPTE Pt)
{
ASSERT(FALSE);
return 0;
}
static ULONG64 MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address)
{
MMPTE Pte, *PointerPte;
PointerPte = MmGetPageTableForProcess(Process, Address, FALSE);
if (PointerPte)
{
Pte = *PointerPte;
MmUnmapPageTable(PointerPte);
return Pte.u.Long;
}
return 0;
return !Pte.u.Hard.Valid && Pte.u.Soft.Transition;
}
VOID
@ -361,8 +324,12 @@ MmGetPageFileMapping(
PVOID Address,
SWAPENTRY* SwapEntry)
{
ULONG64 Entry = MmGetPageEntryForProcess(Process, Address);
*SwapEntry = Entry >> 1;
PMMPTE PointerPte;
ASSERT(Process == PsGetCurrentProcess());
PointerPte = MiAddressToPte(Address);
*SwapEntry = PointerPte->u.Long >> 1;
}
BOOLEAN