From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PULL 2/3] apic: fix loss of IPI due to masked ExtINT
Date: Mon, 24 Nov 2014 14:40:48 +0100 [thread overview]
Message-ID: <1416836449-2599-3-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1416836449-2599-1-git-send-email-pbonzini@redhat.com>
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>
---
hw/intc/apic.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/hw/intc/apic.c b/hw/intc/apic.c
index 0653409..6ec5861 100644
--- a/hw/intc/apic.c
+++ b/hw/intc/apic.c
@@ -188,7 +188,7 @@ void apic_deliver_pic_intr(DeviceState *dev, int level)
apic_reset_bit(s->irr, lvt & 0xff);
/* fall through */
case APIC_DM_EXTINT:
- cpu_reset_interrupt(CPU(s->cpu), CPU_INTERRUPT_HARD);
+ apic_update_irq(s);
break;
}
}
@@ -376,6 +376,8 @@ static void apic_update_irq(APICCommonState *s)
cpu_interrupt(cpu, CPU_INTERRUPT_POLL);
} else if (apic_irq_pending(s) > 0) {
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);
}
}
--
1.8.3.1
next prev parent reply other threads:[~2014-11-24 13:41 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-24 13:40 [Qemu-devel] [PULL for-2.2 0/3] APIC fixes for 2014-11-24 Paolo Bonzini
2014-11-24 13:40 ` [Qemu-devel] [PULL 1/3] apic: avoid getting out of halted state on masked PIC interrupts Paolo Bonzini
2014-11-24 13:40 ` Paolo Bonzini [this message]
2014-11-24 13:40 ` [Qemu-devel] [PULL 3/3] apic: fix incorrect handling of ExtINT interrupts wrt processor priority Paolo Bonzini
2014-11-24 15:01 ` [Qemu-devel] [PULL for-2.2 0/3] APIC fixes for 2014-11-24 Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1416836449-2599-3-git-send-email-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).