https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ce65553eaa0506962064f8...
commit ce65553eaa0506962064f8f2224b149ad45d6bdb Author: Jérôme Gardou jerome.gardou@reactos.org AuthorDate: Fri Jul 23 17:14:47 2021 +0200 Commit: Jérôme Gardou zefklop@users.noreply.github.com 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)