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

commit ce65553eaa0506962064f8f2224b149ad45d6bdb
Author:     Jérôme Gardou <[email protected]>
AuthorDate: Fri Jul 23 17:14:47 2021 +0200
Commit:     Jérôme Gardou <[email protected]>
CommitDate: Tue Jul 27 15:36:55 2021 +0200

    [NTOS:MM] Annotate some functions with regards to MmPfnLock
    
    Also fix MI_ASSERT_PFN_LOCK_HELD macro.
    Now in debug builds, SpinLocks are always non-zero when held.
---
 ntoskrnl/include/internal/mm.h | 29 ++++++++++++++++++++++++++---
 ntoskrnl/mm/section.c          |  6 ++++++
 2 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/ntoskrnl/include/internal/mm.h b/ntoskrnl/include/internal/mm.h
index e8ace692bd2..bb27544a949 100644
--- a/ntoskrnl/include/internal/mm.h
+++ b/ntoskrnl/include/internal/mm.h
@@ -46,6 +46,8 @@ extern SIZE_T MmtotalCommitLimitMaximum;
 extern PVOID MiDebugMapping; // internal
 extern PMMPTE MmDebugPte; // internal
 
+extern KSPIN_LOCK MmPfnLock;
+
 struct _KTRAP_FRAME;
 struct _EPROCESS;
 struct _MM_RMAP_ENTRY;
@@ -940,7 +942,11 @@ MmGetSectionAssociation(PFN_NUMBER Page,
                         PLARGE_INTEGER Offset);
 
 /* freelist.c **********************************************************/
-
+_IRQL_raises_(DISPATCH_LEVEL)
+_IRQL_requires_max_(DISPATCH_LEVEL)
+_Requires_lock_not_held_(MmPfnLock)
+_Acquires_lock_(MmPfnLock)
+_IRQL_saves_
 FORCEINLINE
 KIRQL
 MiAcquirePfnLock(VOID)
@@ -948,14 +954,20 @@ MiAcquirePfnLock(VOID)
     return KeAcquireQueuedSpinLock(LockQueuePfnLock);
 }
 
+_Requires_lock_held_(MmPfnLock)
+_Releases_lock_(MmPfnLock)
+_IRQL_requires_(DISPATCH_LEVEL)
 FORCEINLINE
 VOID
 MiReleasePfnLock(
-    _In_ KIRQL OldIrql)
+    _In_ _IRQL_restores_ KIRQL OldIrql)
 {
     KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
 }
 
+_IRQL_requires_min_(DISPATCH_LEVEL)
+_Requires_lock_not_held_(MmPfnLock)
+_Acquires_lock_(MmPfnLock)
 FORCEINLINE
 VOID
 MiAcquirePfnLockAtDpcLevel(VOID)
@@ -967,6 +979,9 @@ MiAcquirePfnLockAtDpcLevel(VOID)
     KeAcquireQueuedSpinLockAtDpcLevel(LockQueue);
 }
 
+_Requires_lock_held_(MmPfnLock)
+_Releases_lock_(MmPfnLock)
+_IRQL_requires_min_(DISPATCH_LEVEL)
 FORCEINLINE
 VOID
 MiReleasePfnLockFromDpcLevel(VOID)
@@ -978,7 +993,7 @@ MiReleasePfnLockFromDpcLevel(VOID)
     ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
 }
 
-#define MI_ASSERT_PFN_LOCK_HELD() ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL)
+#define MI_ASSERT_PFN_LOCK_HELD() NT_ASSERT((KeGetCurrentIrql() >= 
DISPATCH_LEVEL) && (MmPfnLock != 0))
 
 FORCEINLINE
 PMMPFN
@@ -1476,10 +1491,18 @@ MmUnsharePageEntrySectionSegment(PMEMORY_AREA 
MemoryArea,
                                  BOOLEAN PageOut,
                                  ULONG_PTR *InEntry);
 
+_When_(OldIrql == MM_NOIRQL, _IRQL_requires_max_(DISPATCH_LEVEL))
+_When_(OldIrql == MM_NOIRQL, _Requires_lock_not_held_(MmPfnLock))
+_When_(OldIrql != MM_NOIRQL, _Requires_lock_held_(MmPfnLock))
+_When_(OldIrql != MM_NOIRQL, _Releases_lock_(MmPfnLock))
+_When_(OldIrql != MM_NOIRQL, _IRQL_restores_(OldIrql))
+_When_(OldIrql != MM_NOIRQL, _IRQL_requires_(DISPATCH_LEVEL))
 VOID
 NTAPI
 MmDereferenceSegmentWithLock(PMM_SECTION_SEGMENT Segment, KIRQL OldIrql);
 
+_IRQL_requires_max_(DISPATCH_LEVEL)
+_Requires_lock_not_held_(MmPfnLock)
 FORCEINLINE
 VOID
 MmDereferenceSegment(PMM_SECTION_SEGMENT Segment)
diff --git a/ntoskrnl/mm/section.c b/ntoskrnl/mm/section.c
index c59f45077fd..c4b89125f06 100644
--- a/ntoskrnl/mm/section.c
+++ b/ntoskrnl/mm/section.c
@@ -987,6 +987,12 @@ FreeSegmentPage(PMM_SECTION_SEGMENT Segment, 
PLARGE_INTEGER Offset)
     MmReleasePageMemoryConsumer(MC_USER, Page);
 }
 
+_When_(OldIrql == MM_NOIRQL, _IRQL_requires_max_(DISPATCH_LEVEL))
+_When_(OldIrql == MM_NOIRQL, _Requires_lock_not_held_(MmPfnLock))
+_When_(OldIrql != MM_NOIRQL, _Requires_lock_held_(MmPfnLock))
+_When_(OldIrql != MM_NOIRQL, _Releases_lock_(MmPfnLock))
+_When_(OldIrql != MM_NOIRQL, _IRQL_restores_(OldIrql))
+_When_(OldIrql != MM_NOIRQL, _IRQL_requires_(DISPATCH_LEVEL))
 VOID
 NTAPI
 MmDereferenceSegmentWithLock(PMM_SECTION_SEGMENT Segment, KIRQL OldIrql)

Reply via email to