https://git.reactos.org/?p=reactos.git;a=commitdiff;h=37d0a9c3f45ec423eadb1…
commit 37d0a9c3f45ec423eadb14e17bf0ace3a1af7499
Author: Jérôme Gardou <jerome.gardou(a)reactos.org>
AuthorDate: Fri May 21 09:44:32 2021 +0200
Commit: Jérôme Gardou <zefklop(a)users.noreply.github.com>
CommitDate: Tue Jun 29 11:49:20 2021 +0200
[NTOS:KE] Unconditionally check IRQL when acquiring & releasing spinlock at
DISPATCH_LEVEL
---
ntoskrnl/include/internal/ke.h | 10 ++++++++--
ntoskrnl/ke/spinlock.c | 25 +++++++++++++++++++++----
2 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/ntoskrnl/include/internal/ke.h b/ntoskrnl/include/internal/ke.h
index 92558517f0f..ae255961388 100644
--- a/ntoskrnl/include/internal/ke.h
+++ b/ntoskrnl/include/internal/ke.h
@@ -986,16 +986,22 @@ VOID
NTAPI
KeThawExecution(IN BOOLEAN Enable);
+_IRQL_requires_min_(DISPATCH_LEVEL)
+_Acquires_nonreentrant_lock_(*LockHandle->Lock)
+_Acquires_exclusive_lock_(*LockHandle->Lock)
VOID
FASTCALL
KeAcquireQueuedSpinLockAtDpcLevel(
- IN OUT PKSPIN_LOCK_QUEUE LockQueue
+ _Inout_ PKSPIN_LOCK_QUEUE LockQueue
);
+_IRQL_requires_min_(DISPATCH_LEVEL)
+_Releases_nonreentrant_lock_(*LockHandle->Lock)
+_Releases_exclusive_lock_(*LockHandle->Lock)
VOID
FASTCALL
KeReleaseQueuedSpinLockFromDpcLevel(
- IN OUT PKSPIN_LOCK_QUEUE LockQueue
+ _Inout_ PKSPIN_LOCK_QUEUE LockQueue
);
VOID
diff --git a/ntoskrnl/ke/spinlock.c b/ntoskrnl/ke/spinlock.c
index deb52b85d29..d382cbf5055 100644
--- a/ntoskrnl/ke/spinlock.c
+++ b/ntoskrnl/ke/spinlock.c
@@ -94,11 +94,14 @@ KeReleaseQueuedSpinLockFromDpcLevel(IN PKSPIN_LOCK_QUEUE LockHandle)
// HACK: Hacked to work like normal spinlocks
//
+_IRQL_requires_min_(DISPATCH_LEVEL)
+_Acquires_nonreentrant_lock_(*LockHandle->Lock)
+_Acquires_exclusive_lock_(*LockHandle->Lock)
VOID
FASTCALL
-KeAcquireQueuedSpinLockAtDpcLevel(IN PKSPIN_LOCK_QUEUE LockHandle)
+KeAcquireQueuedSpinLockAtDpcLevel(_Inout_ PKSPIN_LOCK_QUEUE LockHandle)
{
-#ifdef CONFIG_SMP
+#if defined(CONFIG_SMP) || DBG
/* Make sure we are at DPC or above! */
if (KeGetCurrentIrql() < DISPATCH_LEVEL)
{
@@ -115,11 +118,14 @@ KeAcquireQueuedSpinLockAtDpcLevel(IN PKSPIN_LOCK_QUEUE LockHandle)
KxAcquireSpinLock(LockHandle->Lock);
}
+_IRQL_requires_min_(DISPATCH_LEVEL)
+_Releases_nonreentrant_lock_(*LockHandle->Lock)
+_Releases_exclusive_lock_(*LockHandle->Lock)
VOID
FASTCALL
-KeReleaseQueuedSpinLockFromDpcLevel(IN PKSPIN_LOCK_QUEUE LockHandle)
+KeReleaseQueuedSpinLockFromDpcLevel(_Inout_ PKSPIN_LOCK_QUEUE LockHandle)
{
-#ifdef CONFIG_SMP
+#if defined(CONFIG_SMP) || DBG
/* Make sure we are at DPC or above! */
if (KeGetCurrentIrql() < DISPATCH_LEVEL)
{
@@ -303,6 +309,17 @@ FASTCALL
KeTryToAcquireSpinLockAtDpcLevel(IN OUT PKSPIN_LOCK SpinLock)
{
#if DBG
+ /* Make sure we are at DPC or above! */
+ if (KeGetCurrentIrql() < DISPATCH_LEVEL)
+ {
+ /* We aren't -- bugcheck */
+ KeBugCheckEx(IRQL_NOT_GREATER_OR_EQUAL,
+ (ULONG_PTR)SpinLock,
+ KeGetCurrentIrql(),
+ 0,
+ 0);
+ }
+
/* Make sure that we don't own the lock already */
if (((KSPIN_LOCK)KeGetCurrentThread() | 1) == *SpinLock)
{