https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8404d1a6ff897f5210860…
commit 8404d1a6ff897f5210860ba52d70c3a6e86f3fbb
Author: Jérôme Gardou <jerome.gardou(a)reactos.org>
AuthorDate: Wed Apr 7 23:05:51 2021 +0200
Commit: Jérôme Gardou <jerome.gardou(a)reactos.org>
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