[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.
This commit is contained in:
Oleg Dubinskiy 2024-01-20 15:55:20 +01:00 committed by GitHub
parent 3306a16e84
commit f72d6dd4c5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 24 additions and 0 deletions

View file

@ -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
{

View file

@ -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
{

View file

@ -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
{