- Do not allow software interrupts to preempt code running with interrupts disabled during KfLowerIrql

svn path=/trunk/; revision=54418
This commit is contained in:
Cameron Gutman 2011-11-18 18:53:41 +00:00
parent 01323f857e
commit aefaa2f4f9

View file

@ -666,25 +666,29 @@ KfLowerIrql(IN KIRQL OldIrql)
/* Set old IRQL */ /* Set old IRQL */
Pcr->Irql = OldIrql; Pcr->Irql = OldIrql;
/* Check for pending software interrupts and compare with current IRQL */ /* Make sure interrupts were enabled */
PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[OldIrql]; if (EFlags & EFLAGS_INTERRUPT_MASK)
if (PendingIrqlMask)
{ {
/* Check if pending IRQL affects hardware state */ /* Check for pending software interrupts and compare with current IRQL */
BitScanReverse(&PendingIrql, PendingIrqlMask); PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[OldIrql];
if (PendingIrql > DISPATCH_LEVEL) if (PendingIrqlMask)
{ {
/* Set new PIC mask */ /* Check if pending IRQL affects hardware state */
Mask.Both = Pcr->IDR; BitScanReverse(&PendingIrql, PendingIrqlMask);
__outbyte(PIC1_DATA_PORT, Mask.Master); if (PendingIrql > DISPATCH_LEVEL)
__outbyte(PIC2_DATA_PORT, Mask.Slave); {
/* Set new PIC mask */
Mask.Both = Pcr->IDR;
__outbyte(PIC1_DATA_PORT, Mask.Master);
__outbyte(PIC2_DATA_PORT, Mask.Slave);
/* Clear IRR bit */ /* Clear IRR bit */
Pcr->IRR ^= (1 << PendingIrql); Pcr->IRR ^= (1 << PendingIrql);
}
/* Now handle pending interrupt */
SWInterruptHandlerTable[PendingIrql]();
} }
/* Now handle pending interrupt */
SWInterruptHandlerTable[PendingIrql]();
} }
/* Restore interrupt state */ /* Restore interrupt state */