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

commit e685b25e35c9d6dfbe2139ac71f7378b1f9e6d0f
Author:     Timo Kreuzer <[email protected]>
AuthorDate: Thu Sep 28 20:29:43 2023 +0300
Commit:     Timo Kreuzer <[email protected]>
CommitDate: Sat Oct 7 10:58:30 2023 +0300

    [NTOS:MM/x64] Temporarily release AddressCreationLock in 
MmCreateVirtualMappingUnsafeEx
    
    This is a hack, because the kernel mode path can incur a recursive page 
fault with the AddressCreationLock acquired, which would lead to a recursive 
acquisition, once we do proper locking in MmAccessFault.
    To properly fix this the PDE must be made valid, similar to the user mode 
path, but that is not that simple...
---
 ntoskrnl/mm/i386/page.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/ntoskrnl/mm/i386/page.c b/ntoskrnl/mm/i386/page.c
index df13cb013e2..eeccef94346 100644
--- a/ntoskrnl/mm/i386/page.c
+++ b/ntoskrnl/mm/i386/page.c
@@ -637,6 +637,9 @@ MmCreateVirtualMappingUnsafeEx(
     PMMPTE PointerPte;
     MMPTE TempPte;
     ULONG_PTR Pte;
+#ifdef _M_AMD64
+    BOOLEAN LockReleased = FALSE;
+#endif
 
     DPRINT("MmCreateVirtualMappingUnsafe(%p, %p, %lu, %x)\n",
            Process, Address, flProtect, Page);
@@ -665,6 +668,15 @@ MmCreateVirtualMappingUnsafeEx(
         if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
             MiFillSystemPageDirectory(Address, PAGE_SIZE);
 #endif
+
+#ifdef _M_AMD64
+        /* This is a temporary hack, because we can incur a recursive page 
fault when accessing the PDE */
+        if (PsIdleProcess->AddressCreationLock.Owner == KeGetCurrentThread())
+        {
+            MmUnlockAddressSpace(MmGetKernelAddressSpace());
+            LockReleased = TRUE;
+        }
+#endif
     }
     else
     {
@@ -715,6 +727,15 @@ MmCreateVirtualMappingUnsafeEx(
         MiIncrementPageTableReferences(Address);
         MiUnlockProcessWorkingSetUnsafe(Process, PsGetCurrentThread());
     }
+#ifdef _M_AMD64
+    else
+    {
+        if (LockReleased)
+        {
+            MmLockAddressSpace(MmGetKernelAddressSpace());
+        }
+    }
+#endif
 
     return(STATUS_SUCCESS);
 }

Reply via email to