2009-03-10 00:31:14 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS Kernel
|
|
|
|
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
|
|
|
* FILE: ntoskrnl/mm/hypermap.c
|
|
|
|
* PURPOSE: Hyperspace Mapping Functionality
|
|
|
|
* PROGRAMMERS: ReactOS Portable Systems Group
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES *******************************************************************/
|
|
|
|
|
|
|
|
#include <ntoskrnl.h>
|
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
|
|
|
/* GLOBALS ********************************************************************/
|
|
|
|
|
2009-06-23 06:39:10 +00:00
|
|
|
PMMPTE MmFirstReservedMappingPte, MmLastReservedMappingPte;
|
2009-03-10 00:31:14 +00:00
|
|
|
MMPTE HyperTemplatePte;
|
|
|
|
PEPROCESS HyperProcess;
|
|
|
|
KIRQL HyperIrql;
|
|
|
|
|
|
|
|
/* PRIVATE FUNCTIONS **********************************************************/
|
|
|
|
|
|
|
|
PVOID
|
|
|
|
NTAPI
|
|
|
|
MiMapPageInHyperSpace(IN PEPROCESS Process,
|
|
|
|
IN PFN_NUMBER Page,
|
|
|
|
IN PKIRQL OldIrql)
|
|
|
|
{
|
|
|
|
MMPTE TempPte;
|
|
|
|
PMMPTE PointerPte;
|
|
|
|
PFN_NUMBER Offset;
|
2009-03-29 19:32:37 +00:00
|
|
|
PVOID Address;
|
|
|
|
|
|
|
|
/* Never accept page 0 */
|
2009-03-10 00:31:14 +00:00
|
|
|
ASSERT(Page != 0);
|
2009-03-29 19:32:37 +00:00
|
|
|
|
|
|
|
/* Build the PTE */
|
2009-03-10 00:31:14 +00:00
|
|
|
TempPte = HyperTemplatePte;
|
|
|
|
TempPte.u.Hard.PageFrameNumber = Page;
|
2009-03-29 19:32:37 +00:00
|
|
|
|
|
|
|
/* Pick the first hyperspace PTE */
|
2009-03-10 00:31:14 +00:00
|
|
|
PointerPte = MmFirstReservedMappingPte;
|
|
|
|
|
2009-03-29 19:32:37 +00:00
|
|
|
/* Acquire the hyperlock */
|
2009-03-10 00:31:14 +00:00
|
|
|
ASSERT(Process == PsGetCurrentProcess());
|
2009-03-15 02:05:40 +00:00
|
|
|
KeAcquireSpinLock(&Process->HyperSpaceLock, OldIrql);
|
2009-03-29 19:32:37 +00:00
|
|
|
|
|
|
|
/* Now get the first free PTE */
|
2009-03-10 00:31:14 +00:00
|
|
|
Offset = PFN_FROM_PTE(PointerPte);
|
|
|
|
if (!Offset)
|
|
|
|
{
|
2009-03-29 19:32:37 +00:00
|
|
|
/* Reset the PTEs */
|
2009-03-10 00:31:14 +00:00
|
|
|
Offset = MI_HYPERSPACE_PTES;
|
|
|
|
KeFlushProcessTb();
|
|
|
|
}
|
2009-03-29 19:32:37 +00:00
|
|
|
|
|
|
|
/* Prepare the next PTE */
|
2009-03-10 00:31:14 +00:00
|
|
|
PointerPte->u.Hard.PageFrameNumber = Offset - 1;
|
2009-03-29 19:32:37 +00:00
|
|
|
|
|
|
|
/* Write the current PTE */
|
2009-03-10 00:31:14 +00:00
|
|
|
PointerPte += Offset;
|
|
|
|
ASSERT(PointerPte->u.Hard.Valid == 0);
|
|
|
|
ASSERT(TempPte.u.Hard.Valid == 1);
|
|
|
|
*PointerPte = TempPte;
|
2009-03-29 19:32:37 +00:00
|
|
|
|
|
|
|
/* Return the address */
|
2009-03-10 00:31:14 +00:00
|
|
|
Address = (PVOID)((ULONG_PTR)PointerPte << 10);
|
|
|
|
return Address;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
MiUnmapPageInHyperSpace(IN PEPROCESS Process,
|
|
|
|
IN PVOID Address,
|
|
|
|
IN KIRQL OldIrql)
|
|
|
|
{
|
|
|
|
ASSERT(Process == PsGetCurrentProcess());
|
|
|
|
|
2009-03-29 19:32:37 +00:00
|
|
|
/* Blow away the mapping */
|
2009-03-10 00:31:14 +00:00
|
|
|
MiAddressToPte(Address)->u.Long = 0;
|
2009-03-29 19:32:37 +00:00
|
|
|
|
|
|
|
/* Release the hyperlock */
|
2009-03-15 02:05:40 +00:00
|
|
|
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
|
|
|
|
KeReleaseSpinLock(&Process->HyperSpaceLock, OldIrql);
|
2009-03-10 00:31:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PVOID
|
|
|
|
NTAPI
|
2009-03-10 20:52:39 +00:00
|
|
|
MiMapPageToZeroInHyperSpace(IN PFN_NUMBER Page)
|
2009-03-10 00:31:14 +00:00
|
|
|
{
|
|
|
|
MMPTE TempPte;
|
|
|
|
PMMPTE PointerPte;
|
|
|
|
PVOID Address;
|
2009-03-14 01:20:18 +00:00
|
|
|
|
2009-03-29 19:32:37 +00:00
|
|
|
/* Never accept page 0 */
|
2009-03-10 00:31:14 +00:00
|
|
|
ASSERT(Page != 0);
|
2009-03-14 01:20:18 +00:00
|
|
|
|
2009-03-29 19:32:37 +00:00
|
|
|
/* Build the PTE */
|
2009-03-10 00:31:14 +00:00
|
|
|
TempPte = HyperTemplatePte;
|
|
|
|
TempPte.u.Hard.PageFrameNumber = Page;
|
2009-03-14 01:20:18 +00:00
|
|
|
|
2009-03-29 19:32:37 +00:00
|
|
|
/* Get the Zero PTE and its address */
|
2009-03-15 01:23:47 +00:00
|
|
|
PointerPte = MiAddressToPte(MI_ZERO_PTE);
|
|
|
|
Address = (PVOID)((ULONG_PTR)PointerPte << 10);
|
2009-03-14 01:20:18 +00:00
|
|
|
|
2009-03-29 19:32:37 +00:00
|
|
|
/* Invalidate the old address */
|
2009-03-15 01:23:47 +00:00
|
|
|
__invlpg(Address);
|
2009-03-14 01:20:18 +00:00
|
|
|
|
2009-03-29 19:32:37 +00:00
|
|
|
/* Write the current PTE */
|
2009-03-15 01:23:47 +00:00
|
|
|
TempPte.u.Hard.PageFrameNumber = Page;
|
2009-03-10 00:31:14 +00:00
|
|
|
*PointerPte = TempPte;
|
2009-03-14 01:20:18 +00:00
|
|
|
|
2009-03-29 19:32:37 +00:00
|
|
|
/* Return the address */
|
2009-03-10 00:31:14 +00:00
|
|
|
return Address;
|
|
|
|
}
|