https://git.reactos.org/?p=reactos.git;a=commitdiff;h=73de609917e7cf4e78e092...
commit 73de609917e7cf4e78e092f631ab5ffd7c5326be Author: Timo Kreuzer timo.kreuzer@reactos.org AuthorDate: Mon Apr 10 21:14:06 2023 +0300 Commit: Timo Kreuzer timo.kreuzer@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");