[NTOS:Mm] Implement MmCreatePhysicalMapping and MmDeletePhysicalMapping to handle pyhsical memory sections

This commit is contained in:
Timo Kreuzer 2023-04-10 21:14:06 +03:00
parent 918e331970
commit 73de609917
4 changed files with 89 additions and 12 deletions

View file

@ -1135,6 +1135,14 @@ MmCreateVirtualMappingUnsafe(
PFN_NUMBER Page
);
NTSTATUS
NTAPI
MmCreatePhysicalMapping(
_Inout_opt_ PEPROCESS Process,
_In_ PVOID Address,
_In_ ULONG flProtect,
_In_ PFN_NUMBER Page);
ULONG
NTAPI
MmGetPageProtect(
@ -1291,12 +1299,21 @@ MmGetExecuteOptions(IN PULONG ExecuteOptions);
_Success_(return)
BOOLEAN
MmDeleteVirtualMapping(
_In_opt_ PEPROCESS Process,
_Inout_opt_ PEPROCESS Process,
_In_ PVOID Address,
_Out_opt_ BOOLEAN* WasDirty,
_Out_opt_ PPFN_NUMBER Page
);
_Success_(return)
BOOLEAN
MmDeletePhysicalMapping(
_Inout_opt_ PEPROCESS Process,
_In_ PVOID Address,
_Out_opt_ BOOLEAN * WasDirty,
_Out_opt_ PPFN_NUMBER Page
);
/* arch/procsup.c ************************************************************/
BOOLEAN

View file

@ -234,11 +234,12 @@ MmGetPfnForProcess(PEPROCESS Process,
*/
_Success_(return)
BOOLEAN
MmDeleteVirtualMapping(
_In_opt_ PEPROCESS Process,
MmDeleteVirtualMappingEx(
_Inout_opt_ PEPROCESS Process,
_In_ PVOID Address,
_Out_opt_ BOOLEAN* WasDirty,
_Out_opt_ PPFN_NUMBER Page)
_Out_opt_ PPFN_NUMBER Page,
_In_ BOOLEAN IsPhysical)
{
PMMPTE PointerPte;
MMPTE OldPte;
@ -322,12 +323,38 @@ MmDeleteVirtualMapping(
}
}
if (!IsPhysical && OldPte.u.Hard.Valid)
{
// TODO: Handle PFN ShareCount
}
MiUnlockProcessWorkingSetUnsafe(Process, PsGetCurrentThread());
}
return OldPte.u.Long != 0;
}
_Success_(return)
BOOLEAN
MmDeleteVirtualMapping(
_Inout_opt_ PEPROCESS Process,
_In_ PVOID Address,
_Out_opt_ BOOLEAN * WasDirty,
_Out_opt_ PPFN_NUMBER Page)
{
return MmDeleteVirtualMappingEx(Process, Address, WasDirty, Page, FALSE);
}
_Success_(return)
BOOLEAN
MmDeletePhysicalMapping(
_Inout_opt_ PEPROCESS Process,
_In_ PVOID Address,
_Out_opt_ BOOLEAN * WasDirty,
_Out_opt_ PPFN_NUMBER Page)
{
return MmDeleteVirtualMappingEx(Process, Address, WasDirty, Page, TRUE);
}
VOID
NTAPI
@ -588,10 +615,12 @@ MmCreatePageFileMapping(PEPROCESS Process,
NTSTATUS
NTAPI
MmCreateVirtualMappingUnsafe(PEPROCESS Process,
PVOID Address,
ULONG flProtect,
PFN_NUMBER Page)
MmCreateVirtualMappingUnsafeEx(
_Inout_opt_ PEPROCESS Process,
_In_ PVOID Address,
_In_ ULONG flProtect,
_In_ PFN_NUMBER Page,
_In_ BOOLEAN IsPhysical)
{
ULONG ProtectionMask;
PMMPTE PointerPte;
@ -654,6 +683,11 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
KeBugCheck(MEMORY_MANAGEMENT);
}
if (!IsPhysical)
{
// TODO: Handle PFN ShareCount
}
/* We don't need to flush the TLB here because it only caches valid translations
* and we're moving this PTE from invalid to valid so it can't be cached right now */
@ -667,6 +701,28 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
return(STATUS_SUCCESS);
}
NTSTATUS
NTAPI
MmCreateVirtualMappingUnsafe(
_Inout_opt_ PEPROCESS Process,
_In_ PVOID Address,
_In_ ULONG flProtect,
_In_ PFN_NUMBER Page)
{
return MmCreateVirtualMappingUnsafeEx(Process, Address, flProtect, Page, FALSE);
}
NTSTATUS
NTAPI
MmCreatePhysicalMapping(
_Inout_opt_ PEPROCESS Process,
_In_ PVOID Address,
_In_ ULONG flProtect,
_In_ PFN_NUMBER Page)
{
return MmCreateVirtualMappingUnsafeEx(Process, Address, flProtect, Page, TRUE);
}
NTSTATUS
NTAPI
MmCreateVirtualMapping(PEPROCESS Process,

View file

@ -322,6 +322,10 @@ MmFreeMemoryArea(
/* We'll have to do some cleanup when we're on the page file */
DoFree = TRUE;
}
else if (FreePage == NULL)
{
DoFree = MmDeletePhysicalMapping(Process, (PVOID)Address, &Dirty, &Page);
}
else
{
DoFree = MmDeleteVirtualMapping(Process, (PVOID)Address, &Dirty, &Page);

View file

@ -1689,10 +1689,10 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
* Just map the desired physical page
*/
Page = (PFN_NUMBER)(Offset.QuadPart >> PAGE_SHIFT);
Status = MmCreateVirtualMappingUnsafe(Process,
PAddress,
Region->Protect,
Page);
Status = MmCreatePhysicalMapping(Process,
PAddress,
Region->Protect,
Page);
if (!NT_SUCCESS(Status))
{
DPRINT("MmCreateVirtualMappingUnsafe failed, not out of memory\n");