|
|
@@ -2027,21 +2027,32 @@ __visible void __irq_entry smp_spurious_interrupt(struct pt_regs *regs)
|
|
|
entering_irq();
|
|
|
trace_spurious_apic_entry(vector);
|
|
|
|
|
|
+ inc_irq_stat(irq_spurious_count);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If this is a spurious interrupt then do not acknowledge
|
|
|
+ */
|
|
|
+ if (vector == SPURIOUS_APIC_VECTOR) {
|
|
|
+ /* See SDM vol 3 */
|
|
|
+ pr_info("Spurious APIC interrupt (vector 0xFF) on CPU#%d, should never happen.\n",
|
|
|
+ smp_processor_id());
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
/*
|
|
|
- * Check if this really is a spurious interrupt and ACK it
|
|
|
- * if it is a vectored one. Just in case...
|
|
|
- * Spurious interrupts should not be ACKed.
|
|
|
+ * If it is a vectored one, verify it's set in the ISR. If set,
|
|
|
+ * acknowledge it.
|
|
|
*/
|
|
|
v = apic_read(APIC_ISR + ((vector & ~0x1f) >> 1));
|
|
|
- if (v & (1 << (vector & 0x1f)))
|
|
|
+ if (v & (1 << (vector & 0x1f))) {
|
|
|
+ pr_info("Spurious interrupt (vector 0x%02x) on CPU#%d. Acked\n",
|
|
|
+ vector, smp_processor_id());
|
|
|
ack_APIC_irq();
|
|
|
-
|
|
|
- inc_irq_stat(irq_spurious_count);
|
|
|
-
|
|
|
- /* see sw-dev-man vol 3, chapter 7.4.13.5 */
|
|
|
- pr_info("spurious APIC interrupt through vector %02x on CPU#%d, "
|
|
|
- "should never happen.\n", vector, smp_processor_id());
|
|
|
-
|
|
|
+ } else {
|
|
|
+ pr_info("Spurious interrupt (vector 0x%02x) on CPU#%d. Not pending!\n",
|
|
|
+ vector, smp_processor_id());
|
|
|
+ }
|
|
|
+out:
|
|
|
trace_spurious_apic_exit(vector);
|
|
|
exiting_irq();
|
|
|
}
|