[NTOS:MM] Get rid of "compatibility layer" for hyper space mappings

Let's call that a bug layer instead.
This commit is contained in:
Jérôme Gardou 2020-12-29 19:15:04 +01:00
parent 57e8684bc6
commit 0919324772
3 changed files with 43 additions and 53 deletions

View file

@ -993,10 +993,6 @@ MmZeroPageThread(
); );
/* hypermap.c *****************************************************************/ /* hypermap.c *****************************************************************/
extern PEPROCESS HyperProcess;
extern KIRQL HyperIrql;
PVOID PVOID
NTAPI NTAPI
MiMapPageInHyperSpace(IN PEPROCESS Process, MiMapPageInHyperSpace(IN PEPROCESS Process,
@ -1019,19 +1015,6 @@ NTAPI
MiUnmapPagesInZeroSpace(IN PVOID VirtualAddress, MiUnmapPagesInZeroSpace(IN PVOID VirtualAddress,
IN PFN_NUMBER NumberOfPages); IN PFN_NUMBER NumberOfPages);
//
// ReactOS Compatibility Layer
//
FORCEINLINE
PVOID
MmCreateHyperspaceMapping(IN PFN_NUMBER Page)
{
HyperProcess = (PEPROCESS)KeGetCurrentThread()->ApcState.Process;
return MiMapPageInHyperSpace(HyperProcess, Page, &HyperIrql);
}
#define MmDeleteHyperspaceMapping(x) MiUnmapPageInHyperSpace(HyperProcess, x, HyperIrql);
/* i386/page.c *********************************************************/ /* i386/page.c *********************************************************/
NTSTATUS NTSTATUS

View file

@ -20,8 +20,6 @@
PMMPTE MmFirstReservedMappingPte, MmLastReservedMappingPte; PMMPTE MmFirstReservedMappingPte, MmLastReservedMappingPte;
PMMPTE MiFirstReservedZeroingPte; PMMPTE MiFirstReservedZeroingPte;
MMPTE HyperTemplatePte; MMPTE HyperTemplatePte;
PEPROCESS HyperProcess;
KIRQL HyperIrql;
/* PRIVATE FUNCTIONS **********************************************************/ /* PRIVATE FUNCTIONS **********************************************************/

View file

@ -134,12 +134,12 @@ ULONG MmProtectToValue[32] =
/* FUNCTIONS ***************************************************************/ /* FUNCTIONS ***************************************************************/
static BOOLEAN MmUnmapPageTable(PULONG Pt); static BOOLEAN MmUnmapPageTable(PULONG Pt, KIRQL OldIrql);
VOID VOID
MiFlushTlb(PULONG Pt, PVOID Address) MiFlushTlb(PULONG Pt, PVOID Address, KIRQL OldIrql)
{ {
if ((Pt && MmUnmapPageTable(Pt)) || Address >= MmSystemRangeStart) if ((Pt && MmUnmapPageTable(Pt, OldIrql)) || Address >= MmSystemRangeStart)
{ {
KeInvalidateTlbEntry(Address); KeInvalidateTlbEntry(Address);
} }
@ -203,7 +203,7 @@ MiFillSystemPageDirectory(IN PVOID Base,
IN SIZE_T NumberOfBytes); IN SIZE_T NumberOfBytes);
static PULONG static PULONG
MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create) MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create, PKIRQL OldIrql)
{ {
PFN_NUMBER Pfn; PFN_NUMBER Pfn;
PULONG Pt; PULONG Pt;
@ -219,7 +219,9 @@ MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
PMMPDE PdeBase; PMMPDE PdeBase;
ULONG PdeOffset = MiGetPdeOffset(Address); ULONG PdeOffset = MiGetPdeOffset(Address);
PdeBase = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0])); PdeBase = MiMapPageInHyperSpace(PsGetCurrentProcess(),
PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0]),
OldIrql);
if (PdeBase == NULL) if (PdeBase == NULL)
{ {
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
@ -232,7 +234,7 @@ MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
if (!Create) if (!Create)
{ {
MmDeleteHyperspaceMapping(PdeBase); MiUnmapPageInHyperSpace(PsGetCurrentProcess(), PdeBase, *OldIrql);
return NULL; return NULL;
} }
@ -253,8 +255,8 @@ MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
} }
Pfn = PointerPde->u.Hard.PageFrameNumber; Pfn = PointerPde->u.Hard.PageFrameNumber;
MmDeleteHyperspaceMapping(PdeBase); MiUnmapPageInHyperSpace(PsGetCurrentProcess(), PdeBase, *OldIrql);
Pt = MmCreateHyperspaceMapping(Pfn); Pt = MiMapPageInHyperSpace(PsGetCurrentProcess(), Pfn, OldIrql);
if (Pt == NULL) if (Pt == NULL)
{ {
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
@ -308,17 +310,15 @@ MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
return Pt; return Pt;
} }
static BOOLEAN MmUnmapPageTable(PULONG Pt) static BOOLEAN MmUnmapPageTable(PULONG Pt, KIRQL OldIrql)
{ {
if (!IS_HYPERSPACE(Pt)) if (!IS_HYPERSPACE(Pt))
{ {
return TRUE; return TRUE;
} }
if (Pt) MiUnmapPageInHyperSpace(PsGetCurrentProcess(), Pt, OldIrql);
{
MmDeleteHyperspaceMapping((PVOID)PAGE_ROUND_DOWN(Pt));
}
return FALSE; return FALSE;
} }
@ -326,12 +326,13 @@ static ULONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address)
{ {
ULONG Pte; ULONG Pte;
PULONG Pt; PULONG Pt;
KIRQL OldIrql;
Pt = MmGetPageTableForProcess(Process, Address, FALSE); Pt = MmGetPageTableForProcess(Process, Address, FALSE, &OldIrql);
if (Pt) if (Pt)
{ {
Pte = *Pt; Pte = *Pt;
MmUnmapPageTable(Pt); MmUnmapPageTable(Pt, OldIrql);
return Pte; return Pte;
} }
return 0; return 0;
@ -363,11 +364,12 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address,
PFN_NUMBER Pfn; PFN_NUMBER Pfn;
ULONG Pte; ULONG Pte;
PULONG Pt; PULONG Pt;
KIRQL OldIrql;
DPRINT("MmDeleteVirtualMapping(%p, %p, %p, %p)\n", DPRINT("MmDeleteVirtualMapping(%p, %p, %p, %p)\n",
Process, Address, WasDirty, Page); Process, Address, WasDirty, Page);
Pt = MmGetPageTableForProcess(Process, Address, FALSE); Pt = MmGetPageTableForProcess(Process, Address, FALSE, &OldIrql);
if (Pt == NULL) if (Pt == NULL)
{ {
@ -395,7 +397,7 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address,
/* Flush the TLB since we transitioned this PTE /* Flush the TLB since we transitioned this PTE
* from valid to invalid so any stale translations * from valid to invalid so any stale translations
* are removed from the cache */ * are removed from the cache */
MiFlushTlb(Pt, Address); MiFlushTlb(Pt, Address, OldIrql);
if (Address < MmSystemRangeStart) if (Address < MmSystemRangeStart)
{ {
@ -408,7 +410,7 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address,
} }
else else
{ {
MmUnmapPageTable(Pt); MmUnmapPageTable(Pt, OldIrql);
Pfn = 0; Pfn = 0;
} }
@ -447,8 +449,9 @@ MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
{ {
ULONG Pte; ULONG Pte;
PULONG Pt; PULONG Pt;
KIRQL OldIrql;
Pt = MmGetPageTableForProcess(Process, Address, FALSE); Pt = MmGetPageTableForProcess(Process, Address, FALSE, &OldIrql);
if (Pt == NULL) if (Pt == NULL)
{ {
@ -470,7 +473,7 @@ MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
/* We don't need to flush here because page file entries /* We don't need to flush here because page file entries
* are invalid translations, so the processor won't cache them */ * are invalid translations, so the processor won't cache them */
MmUnmapPageTable(Pt); MmUnmapPageTable(Pt, OldIrql);
if ((Pte & PA_PRESENT) || !(Pte & 0x800)) if ((Pte & PA_PRESENT) || !(Pte & 0x800))
{ {
@ -512,6 +515,7 @@ MmSetCleanPage(PEPROCESS Process, PVOID Address)
{ {
PULONG Pt; PULONG Pt;
ULONG Pte; ULONG Pte;
KIRQL OldIrql;
if (Address < MmSystemRangeStart && Process == NULL) if (Address < MmSystemRangeStart && Process == NULL)
{ {
@ -519,7 +523,7 @@ MmSetCleanPage(PEPROCESS Process, PVOID Address)
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
} }
Pt = MmGetPageTableForProcess(Process, Address, FALSE); Pt = MmGetPageTableForProcess(Process, Address, FALSE, &OldIrql);
if (Pt == NULL) if (Pt == NULL)
{ {
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
@ -536,11 +540,11 @@ MmSetCleanPage(PEPROCESS Process, PVOID Address)
} }
else if (Pte & PA_DIRTY) else if (Pte & PA_DIRTY)
{ {
MiFlushTlb(Pt, Address); MiFlushTlb(Pt, Address, OldIrql);
} }
else else
{ {
MmUnmapPageTable(Pt); MmUnmapPageTable(Pt, OldIrql);
} }
} }
@ -550,6 +554,7 @@ MmSetDirtyPage(PEPROCESS Process, PVOID Address)
{ {
PULONG Pt; PULONG Pt;
ULONG Pte; ULONG Pte;
KIRQL OldIrql;
if (Address < MmSystemRangeStart && Process == NULL) if (Address < MmSystemRangeStart && Process == NULL)
{ {
@ -557,7 +562,7 @@ MmSetDirtyPage(PEPROCESS Process, PVOID Address)
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
} }
Pt = MmGetPageTableForProcess(Process, Address, FALSE); Pt = MmGetPageTableForProcess(Process, Address, FALSE, &OldIrql);
if (Pt == NULL) if (Pt == NULL)
{ {
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
@ -576,7 +581,7 @@ MmSetDirtyPage(PEPROCESS Process, PVOID Address)
{ {
/* The processor will never clear this bit itself, therefore /* The processor will never clear this bit itself, therefore
* we do not need to flush the TLB here when setting it */ * we do not need to flush the TLB here when setting it */
MmUnmapPageTable(Pt); MmUnmapPageTable(Pt, OldIrql);
} }
} }
@ -612,6 +617,7 @@ MmCreatePageFileMapping(PEPROCESS Process,
{ {
PULONG Pt; PULONG Pt;
ULONG Pte; ULONG Pte;
KIRQL OldIrql;
if (Process == NULL && Address < MmSystemRangeStart) if (Process == NULL && Address < MmSystemRangeStart)
{ {
@ -629,7 +635,7 @@ MmCreatePageFileMapping(PEPROCESS Process,
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
} }
Pt = MmGetPageTableForProcess(Process, Address, FALSE); Pt = MmGetPageTableForProcess(Process, Address, FALSE, &OldIrql);
if (Pt == NULL) if (Pt == NULL)
{ {
/* Nobody should page out an address that hasn't even been mapped */ /* Nobody should page out an address that hasn't even been mapped */
@ -638,7 +644,7 @@ MmCreatePageFileMapping(PEPROCESS Process,
{ {
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
} }
Pt = MmGetPageTableForProcess(Process, Address, TRUE); Pt = MmGetPageTableForProcess(Process, Address, TRUE, &OldIrql);
} }
Pte = InterlockedExchangePte(Pt, SwapEntry << 1); Pte = InterlockedExchangePte(Pt, SwapEntry << 1);
if (Pte != 0) if (Pte != 0)
@ -656,7 +662,7 @@ MmCreatePageFileMapping(PEPROCESS Process,
/* We don't need to flush the TLB here because it /* We don't need to flush the TLB here because it
* only caches valid translations and a zero PTE * only caches valid translations and a zero PTE
* is not a valid translation */ * is not a valid translation */
MmUnmapPageTable(Pt); MmUnmapPageTable(Pt, OldIrql);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
@ -676,6 +682,8 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
ULONG oldPdeOffset, PdeOffset; ULONG oldPdeOffset, PdeOffset;
PULONG Pt = NULL; PULONG Pt = NULL;
ULONG Pte; ULONG Pte;
KIRQL OldIrql;
DPRINT("MmCreateVirtualMappingUnsafe(%p, %p, %lu, %p (%x), %lu)\n", DPRINT("MmCreateVirtualMappingUnsafe(%p, %p, %lu, %p (%x), %lu)\n",
Process, Address, flProtect, Pages, *Pages, PageCount); Process, Address, flProtect, Pages, *Pages, PageCount);
@ -738,8 +746,8 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
PdeOffset = ADDR_TO_PDE_OFFSET(Addr); PdeOffset = ADDR_TO_PDE_OFFSET(Addr);
if (oldPdeOffset != PdeOffset) if (oldPdeOffset != PdeOffset)
{ {
if(Pt) MmUnmapPageTable(Pt); if(Pt) MmUnmapPageTable(Pt, OldIrql);
Pt = MmGetPageTableForProcess(Process, Addr, TRUE); Pt = MmGetPageTableForProcess(Process, Addr, TRUE, &OldIrql);
if (Pt == NULL) if (Pt == NULL)
{ {
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
@ -772,7 +780,7 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
} }
ASSERT(Addr > Address); ASSERT(Addr > Address);
MmUnmapPageTable(Pt); MmUnmapPageTable(Pt, OldIrql);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
@ -852,6 +860,7 @@ MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
ULONG Attributes = 0; ULONG Attributes = 0;
PULONG Pt; PULONG Pt;
ULONG Pte; ULONG Pte;
KIRQL OldIrql;
DPRINT("MmSetPageProtect(Process %p Address %p flProtect %x)\n", DPRINT("MmSetPageProtect(Process %p Address %p flProtect %x)\n",
Process, Address, flProtect); Process, Address, flProtect);
@ -868,7 +877,7 @@ MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
Attributes |= PA_USER; Attributes |= PA_USER;
} }
Pt = MmGetPageTableForProcess(Process, Address, FALSE); Pt = MmGetPageTableForProcess(Process, Address, FALSE, &OldIrql);
if (Pt == NULL) if (Pt == NULL)
{ {
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
@ -883,9 +892,9 @@ MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
} }
if((Pte & Attributes) != Attributes) if((Pte & Attributes) != Attributes)
MiFlushTlb(Pt, Address); MiFlushTlb(Pt, Address, OldIrql);
else else
MmUnmapPageTable(Pt); MmUnmapPageTable(Pt, OldIrql);
} }
CODE_SEG("INIT") CODE_SEG("INIT")