qemu/hw/intc
Paolo Bonzini 8092cb7132 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
device

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: Richard Bilson <rbilson@qnx.com>
Tested-by: Richard Bilson <rbilson@qnx.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-11-24 14:37:40 +01:00
..
allwinner-a10-pic.c hw/intc/allwinner-a10-pic: Add missing 'break' 2014-05-13 16:09:38 +01:00
apic.c apic: fix loss of IPI due to masked ExtINT 2014-11-24 14:37:40 +01:00
apic_common.c apic_common: migrate missing fields 2014-11-13 16:13:27 +01:00
arm_gic.c arm_gic: remove unused parameter. 2014-10-24 12:19:11 +01:00
arm_gic_common.c arm_gic: Use GIC_NR_SGIS constant 2014-08-29 15:00:29 +01:00
arm_gic_kvm.c arm: Clean up fragile use of error_is_set() in realize() methods 2014-05-05 19:08:49 +02:00
armv7m_nvic.c arm_gic: remove unused parameter. 2014-10-24 12:19:11 +01:00
etraxfs_pic.c hw: cannot_instantiate_with_device_add_yet due to pointer props 2013-12-24 17:27:17 +01:00
exynos4210_combiner.c savevm: Remove all the unneeded version_minimum_id_old (arm) 2014-05-13 16:09:35 +01:00
exynos4210_gic.c savevm: Remove all the unneeded version_minimum_id_old (arm) 2014-05-13 16:09:35 +01:00
gic_internal.h arm_gic: remove unused parameter. 2014-10-24 12:19:11 +01:00
grlib_irqmp.c hw: cannot_instantiate_with_device_add_yet due to pointer props 2013-12-24 17:27:17 +01:00
heathrow_pic.c savevm: Remove all the unneeded version_minimum_id_old (ppc) 2014-06-16 04:55:26 +02:00
i8259.c Fix debug print warning 2014-09-02 22:38:16 +04:00
i8259_common.c savevm: Remove all the unneeded version_minimum_id_old (x86) 2014-06-16 04:55:26 +02:00
imx_avic.c hw/intc/imx_avic.c: Remove unused function imx_avic_set_prio() 2014-09-29 18:48:47 +01:00
ioapic.c qemu: x86: ignore ioapic polarity 2014-03-09 21:09:38 +02:00
ioapic_common.c savevm: Remove all the unneeded version_minimum_id_old (x86) 2014-06-16 04:55:26 +02:00
lm32_pic.c savevm: Remove all the unneeded version_minimum_id_old (rest) 2014-05-14 15:24:51 +02:00
Makefile.objs s390x: split flic into kvm and non-kvm parts 2014-05-20 13:05:57 +02:00
omap_intc.c hw: cannot_instantiate_with_device_add_yet due to pointer props 2013-12-24 17:27:17 +01:00
openpic.c ppc: convert g_new(qemu_irq usages to g_new0 2014-08-15 18:54:50 +04:00
openpic_kvm.c PPC: openpic_kvm: Only map first occurence in address space 2014-11-04 23:26:11 +01:00
pl190.c sysbus: Set cannot_instantiate_with_device_add_yet 2013-12-23 00:27:22 +01:00
puv3_intc.c puv3_intc: QOM cast cleanup 2013-07-29 21:06:58 +02:00
realview_gic.c realview_gic: Prepare for QOM embedding 2013-11-05 17:47:30 +01:00
s390_flic.c s390x/virtio-ccw: wire up irq routing and irqfds 2014-05-20 13:05:58 +02:00
s390_flic_kvm.c s390x/kvm: inject via flic 2014-06-10 09:50:27 +02:00
sh_intc.c cpu: Make first_cpu and next_cpu CPUState 2013-07-09 21:32:54 +02:00
slavio_intctl.c savevm: Remove all the unneeded version_minimum_id_old (rest) 2014-05-14 15:24:51 +02:00
xics.c xics: Implement xics_ics_free() 2014-06-27 13:48:26 +02:00
xics_kvm.c xics: Disable flags reset on xics reset 2014-06-27 13:48:26 +02:00
xilinx_intc.c intc: xilinx_uartlite: Convert SBD::init -> instance_init 2014-06-09 00:33:03 +02:00