Commit 8092cb71 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

apic: fix loss of IPI due to masked ExtINT

This patch fixes an obscure failure of the QNX kernel on QEMU x86 SMP.
In QNX, all hardware interrupts come via the PIC, and are delivered by
the cpu 0 LAPIC in ExtINT mode, while IPIs are delivered by the LAPIC
in fixed mode.

This bug happens as follows:
- cpu 0 masks a particular PIC interrupt
- IPI sent to cpu 0 (CPU_INTERRUPT_HARD is set)
- before the IPI is accepted, the masked interrupt line is asserted by the

Since the interrupt is masked, apic_deliver_pic_intr will clear
CPU_INTERRUPT_HARD. The IPI will still be set in the APIC irr, but since
CPU_INTERRUPT_HARD is not set the cpu will not notice. Depending on the
scenario this can cause a system hang, i.e. if cpu 0 is expected to unmask
the interrupt.

In order to fix this, do a full check of the APIC before an EXTINT
is acknowledged.  This can result in clearing CPU_INTERRUPT_HARD, but
can also result in delivering the lost IPI.

Reported-by: default avatarRichard Bilson <>
Tested-by: default avatarRichard Bilson <>
Signed-off-by: default avatarPaolo Bonzini <>
parent 60e68042
...@@ -188,7 +188,7 @@ void apic_deliver_pic_intr(DeviceState *dev, int level) ...@@ -188,7 +188,7 @@ void apic_deliver_pic_intr(DeviceState *dev, int level)
apic_reset_bit(s->irr, lvt & 0xff); apic_reset_bit(s->irr, lvt & 0xff);
/* fall through */ /* fall through */
cpu_reset_interrupt(CPU(s->cpu), CPU_INTERRUPT_HARD); apic_update_irq(s);
break; break;
} }
} }
...@@ -376,6 +376,8 @@ static void apic_update_irq(APICCommonState *s) ...@@ -376,6 +376,8 @@ static void apic_update_irq(APICCommonState *s)
cpu_interrupt(cpu, CPU_INTERRUPT_POLL); cpu_interrupt(cpu, CPU_INTERRUPT_POLL);
} else if (apic_irq_pending(s) > 0) { } else if (apic_irq_pending(s) > 0) {
cpu_interrupt(cpu, CPU_INTERRUPT_HARD); cpu_interrupt(cpu, CPU_INTERRUPT_HARD);
} else if (!apic_accept_pic_intr(&s->busdev.qdev) || !pic_get_output(isa_pic)) {
cpu_reset_interrupt(cpu, CPU_INTERRUPT_HARD);
} }
} }
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment