https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f72d6dd4c5071a7c16d0b…
commit f72d6dd4c5071a7c16d0bd842d8ff7bd2549ea4a
Author: Oleg Dubinskiy <oleg.dubinskij30(a)gmail.com>
AuthorDate: Sat Jan 20 15:55:20 2024 +0100
Commit: GitHub <noreply(a)github.com>
CommitDate: Sat Jan 20 15:55:20 2024 +0100
[NTOS:KE] Set IRQL to SYNCH_LEVEL when exiting from idle after the thread is ready for
execution (#6386)
CORE-1697
Raise IRQL to SYNCH_LEVEL when exiting from the idle thread in the
idle loop, in case it is scheduled for execution. Then restore it
back to DISPATCH_LEVEL, after this is done.
This behaviour is a bit similar to the way it's done on x64.
This IRQL raise is necessary only in SMP builds.
Calls are placed in CONFIG_SMP ifdef: this avoids unnecessary IRQL
changes on UP, since SYNCH_LEVEL and DISPATCH_LEVEL are identical
there, unlike in MP, where SYNCH_LEVEL is IPI_LEVEL - 2 actually.
This prevents bugcheck DRIVER_IRQL_NOT_LESS_OR_EQUAL when booting
SMP x86 ReactOS, in KiTimerExpiration when calling it 2nd time.
The BSOD happened due to IRQL levels mismatch.
---
ntoskrnl/ke/amd64/stubs.c | 4 ++++
ntoskrnl/ke/arm/thrdini.c | 10 ++++++++++
ntoskrnl/ke/i386/thrdini.c | 10 ++++++++++
3 files changed, 24 insertions(+)
diff --git a/ntoskrnl/ke/amd64/stubs.c b/ntoskrnl/ke/amd64/stubs.c
index cb2d4a37248..7326f7a2cd0 100644
--- a/ntoskrnl/ke/amd64/stubs.c
+++ b/ntoskrnl/ke/amd64/stubs.c
@@ -139,14 +139,18 @@ KiIdleLoop(VOID)
/* The thread is now running */
NewThread->State = Running;
+#ifdef CONFIG_SMP
/* Do the swap at SYNCH_LEVEL */
KfRaiseIrql(SYNCH_LEVEL);
+#endif
/* Switch away from the idle thread */
KiSwapContext(APC_LEVEL, OldThread);
+#ifdef CONFIG_SMP
/* Go back to DISPATCH_LEVEL */
KeLowerIrql(DISPATCH_LEVEL);
+#endif
}
else
{
diff --git a/ntoskrnl/ke/arm/thrdini.c b/ntoskrnl/ke/arm/thrdini.c
index 89f1664608b..190b73f926c 100644
--- a/ntoskrnl/ke/arm/thrdini.c
+++ b/ntoskrnl/ke/arm/thrdini.c
@@ -193,8 +193,18 @@ KiIdleLoop(VOID)
/* The thread is now running */
NewThread->State = Running;
+#ifdef CONFIG_SMP
+ /* Do the swap at SYNCH_LEVEL */
+ KfRaiseIrql(SYNCH_LEVEL);
+#endif
+
/* Switch away from the idle thread */
KiSwapContext(APC_LEVEL, OldThread);
+
+#ifdef CONFIG_SMP
+ /* Go back to DISPATCH_LEVEL */
+ KeLowerIrql(DISPATCH_LEVEL);
+#endif
}
else
{
diff --git a/ntoskrnl/ke/i386/thrdini.c b/ntoskrnl/ke/i386/thrdini.c
index cfc497bfc69..3214f560872 100644
--- a/ntoskrnl/ke/i386/thrdini.c
+++ b/ntoskrnl/ke/i386/thrdini.c
@@ -300,8 +300,18 @@ KiIdleLoop(VOID)
/* The thread is now running */
NewThread->State = Running;
+#ifdef CONFIG_SMP
+ /* Do the swap at SYNCH_LEVEL */
+ KfRaiseIrql(SYNCH_LEVEL);
+#endif
+
/* Switch away from the idle thread */
KiSwapContext(APC_LEVEL, OldThread);
+
+#ifdef CONFIG_SMP
+ /* Go back to DISPATCH_LEVEL */
+ KeLowerIrql(DISPATCH_LEVEL);
+#endif
}
else
{