https://git.reactos.org/?p=reactos.git;a=commitdiff;h=73de609917e7cf4e78e09…
commit 73de609917e7cf4e78e092f631ab5ffd7c5326be
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Mon Apr 10 21:14:06 2023 +0300
Commit: Timo Kreuzer <timo.kreuzer(a)reactos.org>
CommitDate: Sat Jul 29 14:00:44 2023 +0300
[NTOS:Mm] Implement MmCreatePhysicalMapping and MmDeletePhysicalMapping to handle
pyhsical memory sections
---
ntoskrnl/include/internal/mm.h | 19 +++++++++++-
ntoskrnl/mm/i386/page.c | 70 +++++++++++++++++++++++++++++++++++++-----
ntoskrnl/mm/marea.c | 4 +++
ntoskrnl/mm/section.c | 8 ++---
4 files changed, 89 insertions(+), 12 deletions(-)
diff --git a/ntoskrnl/include/internal/mm.h b/ntoskrnl/include/internal/mm.h
index 5e8ad09a861..5b82d033f37 100644
--- a/ntoskrnl/include/internal/mm.h
+++ b/ntoskrnl/include/internal/mm.h
@@ -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
diff --git a/ntoskrnl/mm/i386/page.c b/ntoskrnl/mm/i386/page.c
index 833c2e2c8d6..4c64dd2a941 100644
--- a/ntoskrnl/mm/i386/page.c
+++ b/ntoskrnl/mm/i386/page.c
@@ -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,
diff --git a/ntoskrnl/mm/marea.c b/ntoskrnl/mm/marea.c
index 8bf8ab72630..ab8bff4a18e 100644
--- a/ntoskrnl/mm/marea.c
+++ b/ntoskrnl/mm/marea.c
@@ -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);
diff --git a/ntoskrnl/mm/section.c b/ntoskrnl/mm/section.c
index 33584a02230..7b2e9d0d694 100644
--- a/ntoskrnl/mm/section.c
+++ b/ntoskrnl/mm/section.c
@@ -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");