diff options
author | Jan Beulich <jbeulich@suse.com> | 2012-05-15 09:18:33 +0200 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2012-05-15 09:18:33 +0200 |
commit | f67f17b13bcf1122f1e95aaf5891236b57fdc527 (patch) | |
tree | 549b2d14590228759ee73044804f8563194e3681 /xen/arch/x86/apic.c | |
parent | 85c4d8a2ab3904353d88a4f79de164b7fda79adb (diff) | |
download | xen-f67f17b13bcf1122f1e95aaf5891236b57fdc527.tar.gz xen-f67f17b13bcf1122f1e95aaf5891236b57fdc527.tar.bz2 xen-f67f17b13bcf1122f1e95aaf5891236b57fdc527.zip |
x86: adjust handling of interrupts coming in via legacy vectors
The debugging code added in c/s 24707:96987c324a4f was hit a (small)
number of times (one report being
http://lists.xen.org/archives/html/xen-devel/2012-05/msg00332.html),
apparently always with a vector within the legacy range. Obviously,
besides legacy vectors not normally expected to be in use on systems
with IO-APIC(s), they should never make it to the IRQ migration logic.
This wasn't being prevented so far: Since we don't have a one-to-one
mapping between vectors and IRQs - legacy IRQs may have two vectors
associated with them (one used in either 8259A, the other used in one
of the IO-APICs) -, vector-to-IRQ translations for legacy vectors (as
used in do_IRQ()) would yield a valid IRQ number despite the IRQ
really being handled via an IO-APIC.
This gets changed here - disable_8259A_irq() zaps the legacy vector-to-
IRQ mapping, and enable_8259A_irq(), should it ever be called for a
particular interrupts, restores it.
The spurious interrupt logic in do_IRQ() gets adjusted too: Interrupts
coming in via legacy vectors presumably didn't get reported through the
IO-APIC/LAPIC pair (as we never program these vectors into any RTE or
LVT). Call ack_APIC_irq() only when the LAPIC's ISR bit says an
interrupt is pending at the given vector. Plus, a new function (pointer)
bogus_8259A_irq() gets used to have the 8259A driver take care of the
bogus interrupt (as outside of automatic EOI mode it may need an EOI to
be issued for it to prevent other interrupts legitimately going through
the 8259As from getting masked out).
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Diffstat (limited to 'xen/arch/x86/apic.c')
-rw-r--r-- | xen/arch/x86/apic.c | 8 |
1 files changed, 2 insertions, 6 deletions
diff --git a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c index e05dd82bb2..50430d2f39 100644 --- a/xen/arch/x86/apic.c +++ b/xen/arch/x86/apic.c @@ -1317,15 +1317,12 @@ void smp_send_state_dump(unsigned int cpu) */ void spurious_interrupt(struct cpu_user_regs *regs) { - unsigned long v; - /* * Check if this is a vectored interrupt (most likely, as this is probably * a request to dump local CPU state). Vectored interrupts are ACKed; * spurious interrupts are not. */ - v = apic_read(APIC_ISR + ((SPURIOUS_APIC_VECTOR & ~0x1f) >> 1)); - if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f))) { + if (apic_isr_read(SPURIOUS_APIC_VECTOR)) { ack_APIC_irq(); if (this_cpu(state_dump_pending)) { this_cpu(state_dump_pending) = 0; @@ -1491,6 +1488,5 @@ enum apic_mode current_local_apic_mode(void) void check_for_unexpected_msi(unsigned int vector) { - unsigned long v = apic_read(APIC_ISR + ((vector & ~0x1f) >> 1)); - BUG_ON(v & (1 << (vector & 0x1f))); + BUG_ON(apic_isr_read(vector)); } |