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 {