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

commit 8404d1a6ff897f5210860ba52d70c3a6e86f3fbb
Author:     Jérôme Gardou <[email protected]>
AuthorDate: Wed Apr 7 23:05:51 2021 +0200
Commit:     Jérôme Gardou <[email protected]>
CommitDate: Wed Apr 7 23:09:26 2021 +0200

    [NTOS:MM] Allow MiMapPageInHyperSpace to be called from DISPATCH_LEVEL
    
    Also annotate it to show its behaviour.
---
 ntoskrnl/include/internal/mm.h | 21 +++++++++++++++------
 ntoskrnl/mm/ARM3/hypermap.c    | 34 ++++++++++++++++++++++++++--------
 2 files changed, 41 insertions(+), 14 deletions(-)

diff --git a/ntoskrnl/include/internal/mm.h b/ntoskrnl/include/internal/mm.h
index 074dbd4e454..4718fcabcc3 100644
--- a/ntoskrnl/include/internal/mm.h
+++ b/ntoskrnl/include/internal/mm.h
@@ -1011,17 +1011,26 @@ MmZeroPageThread(
 );
 
 /* hypermap.c 
*****************************************************************/
+_Acquires_lock_(Process->HyperSpaceLock)
+_When_(OldIrql == 0, _IRQL_requires_(DISPATCH_LEVEL))
+_When_(OldIrql != 0, _IRQL_requires_(PASSIVE_LEVEL))
+_When_(OldIrql != 0, _At_(*OldIrql, IRQL_saves_))
+_When_(OldIrql != 0, _IRQL_raises_(DISPATCH_LEVEL))
 PVOID
 NTAPI
-MiMapPageInHyperSpace(IN PEPROCESS Process,
-                      IN PFN_NUMBER Page,
-                      IN PKIRQL OldIrql);
+MiMapPageInHyperSpace(_In_ PEPROCESS Process,
+                      _In_ PFN_NUMBER Page,
+                      _Out_opt_ PKIRQL OldIrql);
 
+_Requires_lock_held_(Process->HyperSpaceLock)
+_Releases_lock_(Process->HyperSpaceLock)
+_IRQL_requires_(DISPATCH_LEVEL)
+_When_(OldIrql != MM_NOIRQL, _At_(OldIrql, _IRQL_restores_))
 VOID
 NTAPI
-MiUnmapPageInHyperSpace(IN PEPROCESS Process,
-                        IN PVOID Address,
-                        IN KIRQL OldIrql);
+MiUnmapPageInHyperSpace(_In_ PEPROCESS Process,
+                        _In_ PVOID Address,
+                        _In_ KIRQL OldIrql);
 
 PVOID
 NTAPI
diff --git a/ntoskrnl/mm/ARM3/hypermap.c b/ntoskrnl/mm/ARM3/hypermap.c
index 4113814e6a6..88d1a1ea06c 100644
--- a/ntoskrnl/mm/ARM3/hypermap.c
+++ b/ntoskrnl/mm/ARM3/hypermap.c
@@ -23,16 +23,24 @@ MMPTE HyperTemplatePte;
 
 /* PRIVATE FUNCTIONS 
**********************************************************/
 
+_Acquires_lock_(Process->HyperSpaceLock)
+_When_(OldIrql == 0, _IRQL_requires_(DISPATCH_LEVEL))
+_When_(OldIrql != 0, _IRQL_requires_(PASSIVE_LEVEL))
+_When_(OldIrql != 0, _At_(*OldIrql, _IRQL_saves_))
+_When_(OldIrql != 0, _IRQL_raises_(DISPATCH_LEVEL))
 PVOID
 NTAPI
-MiMapPageInHyperSpace(IN PEPROCESS Process,
-                      IN PFN_NUMBER Page,
-                      IN PKIRQL OldIrql)
+MiMapPageInHyperSpace(_In_ PEPROCESS Process,
+                      _In_ PFN_NUMBER Page,
+                      _Out_opt_ PKIRQL OldIrql)
 {
     MMPTE TempPte;
     PMMPTE PointerPte;
     PFN_NUMBER Offset;
 
+    ASSERT(((OldIrql != NULL) && (KeGetCurrentIrql() == PASSIVE_LEVEL))
+        || ((OldIrql == NULL) && (KeGetCurrentIrql() == DISPATCH_LEVEL)));
+
     //
     // Never accept page 0 or non-physical pages
     //
@@ -54,7 +62,10 @@ MiMapPageInHyperSpace(IN PEPROCESS Process,
     // Acquire the hyperlock
     //
     ASSERT(Process == PsGetCurrentProcess());
-    KeAcquireSpinLock(&Process->HyperSpaceLock, OldIrql);
+    if (OldIrql != NULL)
+        KeAcquireSpinLock(&Process->HyperSpaceLock, OldIrql);
+    else
+        KeAcquireSpinLockAtDpcLevel(&Process->HyperSpaceLock);
 
     //
     // Now get the first free PTE
@@ -86,11 +97,15 @@ MiMapPageInHyperSpace(IN PEPROCESS Process,
     return MiPteToAddress(PointerPte);
 }
 
+_Requires_lock_held_(Process->HyperSpaceLock)
+_Releases_lock_(Process->HyperSpaceLock)
+_IRQL_requires_(DISPATCH_LEVEL)
+_When_(OldIrql != MM_NOIRQL, _At_(OldIrql, _IRQL_restores_))
 VOID
 NTAPI
-MiUnmapPageInHyperSpace(IN PEPROCESS Process,
-                        IN PVOID Address,
-                        IN KIRQL OldIrql)
+MiUnmapPageInHyperSpace(_In_ PEPROCESS Process,
+                        _In_ PVOID Address,
+                        _In_ KIRQL OldIrql)
 {
     ASSERT(Process == PsGetCurrentProcess());
 
@@ -103,7 +118,10 @@ MiUnmapPageInHyperSpace(IN PEPROCESS Process,
     // Release the hyperlock
     //
     ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
-    KeReleaseSpinLock(&Process->HyperSpaceLock, OldIrql);
+    if (OldIrql == MM_NOIRQL)
+        KeReleaseSpinLockFromDpcLevel(&Process->HyperSpaceLock);
+    else
+        KeReleaseSpinLock(&Process->HyperSpaceLock, OldIrql);
 }
 
 PVOID

Reply via email to