[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.
This commit is contained in:
Jérôme Gardou 2021-07-23 17:14:47 +02:00 committed by Jérôme Gardou
parent 6150dc994a
commit ce65553eaa
2 changed files with 32 additions and 3 deletions

View file

@ -46,6 +46,8 @@ extern SIZE_T MmtotalCommitLimitMaximum;
extern PVOID MiDebugMapping; // internal extern PVOID MiDebugMapping; // internal
extern PMMPTE MmDebugPte; // internal extern PMMPTE MmDebugPte; // internal
extern KSPIN_LOCK MmPfnLock;
struct _KTRAP_FRAME; struct _KTRAP_FRAME;
struct _EPROCESS; struct _EPROCESS;
struct _MM_RMAP_ENTRY; struct _MM_RMAP_ENTRY;
@ -940,7 +942,11 @@ MmGetSectionAssociation(PFN_NUMBER Page,
PLARGE_INTEGER Offset); PLARGE_INTEGER Offset);
/* freelist.c **********************************************************/ /* freelist.c **********************************************************/
_IRQL_raises_(DISPATCH_LEVEL)
_IRQL_requires_max_(DISPATCH_LEVEL)
_Requires_lock_not_held_(MmPfnLock)
_Acquires_lock_(MmPfnLock)
_IRQL_saves_
FORCEINLINE FORCEINLINE
KIRQL KIRQL
MiAcquirePfnLock(VOID) MiAcquirePfnLock(VOID)
@ -948,14 +954,20 @@ MiAcquirePfnLock(VOID)
return KeAcquireQueuedSpinLock(LockQueuePfnLock); return KeAcquireQueuedSpinLock(LockQueuePfnLock);
} }
_Requires_lock_held_(MmPfnLock)
_Releases_lock_(MmPfnLock)
_IRQL_requires_(DISPATCH_LEVEL)
FORCEINLINE FORCEINLINE
VOID VOID
MiReleasePfnLock( MiReleasePfnLock(
_In_ KIRQL OldIrql) _In_ _IRQL_restores_ KIRQL OldIrql)
{ {
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
} }
_IRQL_requires_min_(DISPATCH_LEVEL)
_Requires_lock_not_held_(MmPfnLock)
_Acquires_lock_(MmPfnLock)
FORCEINLINE FORCEINLINE
VOID VOID
MiAcquirePfnLockAtDpcLevel(VOID) MiAcquirePfnLockAtDpcLevel(VOID)
@ -967,6 +979,9 @@ MiAcquirePfnLockAtDpcLevel(VOID)
KeAcquireQueuedSpinLockAtDpcLevel(LockQueue); KeAcquireQueuedSpinLockAtDpcLevel(LockQueue);
} }
_Requires_lock_held_(MmPfnLock)
_Releases_lock_(MmPfnLock)
_IRQL_requires_min_(DISPATCH_LEVEL)
FORCEINLINE FORCEINLINE
VOID VOID
MiReleasePfnLockFromDpcLevel(VOID) MiReleasePfnLockFromDpcLevel(VOID)
@ -978,7 +993,7 @@ MiReleasePfnLockFromDpcLevel(VOID)
ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); 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 FORCEINLINE
PMMPFN PMMPFN
@ -1476,10 +1491,18 @@ MmUnsharePageEntrySectionSegment(PMEMORY_AREA MemoryArea,
BOOLEAN PageOut, BOOLEAN PageOut,
ULONG_PTR *InEntry); 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 VOID
NTAPI NTAPI
MmDereferenceSegmentWithLock(PMM_SECTION_SEGMENT Segment, KIRQL OldIrql); MmDereferenceSegmentWithLock(PMM_SECTION_SEGMENT Segment, KIRQL OldIrql);
_IRQL_requires_max_(DISPATCH_LEVEL)
_Requires_lock_not_held_(MmPfnLock)
FORCEINLINE FORCEINLINE
VOID VOID
MmDereferenceSegment(PMM_SECTION_SEGMENT Segment) MmDereferenceSegment(PMM_SECTION_SEGMENT Segment)

View file

@ -987,6 +987,12 @@ FreeSegmentPage(PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset)
MmReleasePageMemoryConsumer(MC_USER, Page); 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 VOID
NTAPI NTAPI
MmDereferenceSegmentWithLock(PMM_SECTION_SEGMENT Segment, KIRQL OldIrql) MmDereferenceSegmentWithLock(PMM_SECTION_SEGMENT Segment, KIRQL OldIrql)