Return to an old idea of MiMapPageToZeroInHyperSpace(), "fix" bug #4267.

svn path=/trunk/; revision=40008
This commit is contained in:
Dmitry Gorbachev 2009-03-14 01:20:18 +00:00
parent 67d3295fc6
commit c9901dd8b6

View file

@ -14,8 +14,11 @@
/* GLOBALS ********************************************************************/ /* GLOBALS ********************************************************************/
#define MI_ZEROING_PTES 255
PMMPTE MmFirstReservedMappingPte; PMMPTE MmFirstReservedMappingPte;
PMMPTE MmLastReservedMappingPte; PMMPTE MmLastReservedMappingPte;
PMMPTE MmFirstReservedZeroingPte;
MMPTE HyperTemplatePte; MMPTE HyperTemplatePte;
PEPROCESS HyperProcess; PEPROCESS HyperProcess;
KIRQL HyperIrql; KIRQL HyperIrql;
@ -40,6 +43,8 @@ MiInitHyperSpace(VOID)
MmFirstReservedMappingPte = MiAddressToPte(MI_MAPPING_RANGE_START); MmFirstReservedMappingPte = MiAddressToPte(MI_MAPPING_RANGE_START);
MmLastReservedMappingPte = MiAddressToPte(MI_MAPPING_RANGE_END); MmLastReservedMappingPte = MiAddressToPte(MI_MAPPING_RANGE_END);
MmFirstReservedMappingPte->u.Hard.PageFrameNumber = MI_HYPERSPACE_PTES; MmFirstReservedMappingPte->u.Hard.PageFrameNumber = MI_HYPERSPACE_PTES;
MmFirstReservedZeroingPte = MiAddressToPte(MI_ZERO_PTE);
MmFirstReservedZeroingPte->u.Hard.PageFrameNumber = MI_ZEROING_PTES;
} }
PVOID PVOID
@ -134,38 +139,62 @@ MiMapPageToZeroInHyperSpace(IN PFN_NUMBER Page)
{ {
MMPTE TempPte; MMPTE TempPte;
PMMPTE PointerPte; PMMPTE PointerPte;
PFN_NUMBER Offset;
PVOID Address; PVOID Address;
// //
// Never accept page 0 // Never accept page 0
// //
ASSERT(Page != 0); ASSERT(Page != 0);
// //
// Build the PTE // Build the PTE
// //
TempPte = HyperTemplatePte; TempPte = HyperTemplatePte;
TempPte.u.Hard.PageFrameNumber = Page; TempPte.u.Hard.PageFrameNumber = Page;
// //
// Get the Zero PTE and its address // Pick the first zeroing PTE
// //
PointerPte = MiAddressToPte(MI_ZERO_PTE); PointerPte = MmFirstReservedZeroingPte;
Address = (PVOID)((ULONG_PTR)PointerPte << 10);
// //
// Invalidate the old address // Now get the first free PTE
// //
__invlpg(Address); Offset = PFN_FROM_PTE(PointerPte);
if (!Offset)
{
//
// Reset the PTEs
//
Offset = MI_ZEROING_PTES;
KeFlushProcessTb();
}
//
// Prepare the next PTE
//
PointerPte->u.Hard.PageFrameNumber = Offset - 1;
// //
// Write the current PTE // Write the current PTE
// //
TempPte.u.Hard.PageFrameNumber = Page; PointerPte += Offset;
*PointerPte = TempPte; *PointerPte = TempPte;
// //
// Return the address // Return the address
// //
Address = (PVOID)((ULONG_PTR)PointerPte << 10);
return Address; return Address;
} }
VOID
NTAPI
MiUnmapPageInZeroSpace(IN PVOID Address)
{
//
// Blow away the mapping
//
MiAddressToPte(Address)->u.Long = 0;
}