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

commit f72d6dd4c5071a7c16d0bd842d8ff7bd2549ea4a
Author:     Oleg Dubinskiy <oleg.dubinski...@gmail.com>
AuthorDate: Sat Jan 20 15:55:20 2024 +0100
Commit:     GitHub <nore...@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
         {

Reply via email to