https://git.reactos.org/?p=reactos.git;a=commitdiff;h=73de609917e7cf4e78e092f631ab5ffd7c5326be

commit 73de609917e7cf4e78e092f631ab5ffd7c5326be
Author:     Timo Kreuzer <[email protected]>
AuthorDate: Mon Apr 10 21:14:06 2023 +0300
Commit:     Timo Kreuzer <[email protected]>
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");

Reply via email to