[NTOS:KD64,KE] IRQL is automatically adjusted during calls to KdEnterDebugger() and KdExitDebugger(). (#3942)

Addendum to 608032bd and 835c3023.

The IRQL is actually raised by KeFreezeExecution() and lowered by
KeThawExecution(), always to HIGH_IRQL on MP systems, or if necessary
on UP. These functions are called respectively by KdEnterDebugger()
and KdExitDebugger().
This commit is contained in:
Hermès Bélusca-Maïto 2021-09-05 02:48:20 +02:00
parent 05590079cc
commit 6e9ff14e26
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
3 changed files with 39 additions and 16 deletions

View file

@ -1890,7 +1890,7 @@ KdEnterDebugger(IN PKTRAP_FRAME TrapFrame,
/* Save the current IRQL */
KeGetCurrentPrcb()->DebuggerSavedIRQL = KeGetCurrentIrql();
/* Freeze all CPUs */
/* Freeze all CPUs, raising also the IRQL to HIGH_LEVEL */
Enable = KeFreezeExecution(TrapFrame, ExceptionFrame);
/* Lock the port, save the state and set debugger entered */
@ -1929,7 +1929,7 @@ KdExitDebugger(IN BOOLEAN Enable)
KdRestore(FALSE);
if (KdpPortLocked) KdpPortUnlock();
/* Unfreeze the CPUs */
/* Unfreeze the CPUs, restoring also the IRQL */
KeThawExecution(Enable);
/* Compare time with the one from KdEnterDebugger */

View file

@ -144,11 +144,6 @@ KdpTrap(IN PKTRAP_FRAME TrapFrame,
BOOLEAN Handled;
NTSTATUS ReturnStatus;
USHORT ReturnLength;
KIRQL OldIrql = DISPATCH_LEVEL;
/* Raise if we have to. */
if (KeGetCurrentIrql() < DISPATCH_LEVEL)
OldIrql = KeRaiseIrqlToDpcLevel();
/*
* Check if we got a STATUS_BREAKPOINT with a SubID for Print, Prompt or
@ -262,9 +257,6 @@ KdpTrap(IN PKTRAP_FRAME TrapFrame,
SecondChanceException);
}
if (OldIrql < DISPATCH_LEVEL)
KeLowerIrql(OldIrql);
/* Return TRUE or FALSE to caller */
return Handled;
}

View file

@ -27,15 +27,33 @@ KeFreezeExecution(IN PKTRAP_FRAME TrapFrame,
IN PKEXCEPTION_FRAME ExceptionFrame)
{
BOOLEAN Enable;
KIRQL OldIrql;
/* Disable interrupts and get previous state */
#ifndef CONFIG_SMP
UNREFERENCED_PARAMETER(TrapFrame);
UNREFERENCED_PARAMETER(ExceptionFrame);
#endif
/* Disable interrupts, get previous state and set the freeze flag */
Enable = KeDisableInterrupts();
/* Save freeze flag */
KiFreezeFlag = 4;
/* Save the old IRQL */
KiOldIrql = KeGetCurrentIrql();
#ifndef CONFIG_SMP
/* Raise IRQL if we have to */
OldIrql = KeGetCurrentIrql();
if (OldIrql < DISPATCH_LEVEL)
OldIrql = KeRaiseIrqlToDpcLevel();
#else
/* Raise IRQL to HIGH_LEVEL */
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
#endif
#ifdef CONFIG_SMP
// TODO: Add SMP support.
#endif
/* Save the old IRQL to be restored on unfreeze */
KiOldIrql = OldIrql;
/* Return whether interrupts were enabled */
return Enable;
@ -45,9 +63,22 @@ VOID
NTAPI
KeThawExecution(IN BOOLEAN Enable)
{
#ifdef CONFIG_SMP
// TODO: Add SMP support.
#endif
/* Clear the freeze flag */
KiFreezeFlag = 0;
/* Cleanup CPU caches */
KeFlushCurrentTb();
/* Restore the old IRQL */
#ifndef CONFIG_SMP
if (KiOldIrql < DISPATCH_LEVEL)
#endif
KeLowerIrql(KiOldIrql);
/* Re-enable interrupts */
if (Enable) _enable();
KeRestoreInterrupts(Enable);
}