[PATCH] i386/x86-64: Don't ack the APIC for bad interrupts when the APIC is not enabled
authorAndi Kleen <ak@suse.de>
Fri, 3 Feb 2006 20:51:53 +0000 (21:51 +0100)
committerLinus Torvalds <torvalds@g5.osdl.org>
Sun, 5 Feb 2006 00:43:15 +0000 (16:43 -0800)
It's bad juju to touch the APIC when it hasn't been enabled.
I also moved ack_bad_irq for x86-64 out of line following i386.

Signed-off-by: Andi Kleen <ak@suse.de>
Acked-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/i386/kernel/apic.c
arch/x86_64/kernel/apic.c
include/asm-x86_64/hardirq.h

index acd3f1e34ca6661c331edd0f0369e93da7a744b3..98a5c23cf3df2c2251e0f64a16e294ba696a981d 100644 (file)
@@ -75,8 +75,10 @@ void ack_bad_irq(unsigned int irq)
         * holds up an irq slot - in excessive cases (when multiple
         * unexpected vectors occur) that might lock up the APIC
         * completely.
+        * But only ack when the APIC is enabled -AK
         */
-       ack_APIC_irq();
+       if (!cpu_has_apic)
+               ack_APIC_irq();
 }
 
 void __init apic_intr_init(void)
@@ -1303,6 +1305,7 @@ int __init APIC_init_uniprocessor (void)
        if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
                printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
                        boot_cpu_physical_apicid);
+               clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
                return -1;
        }
 
index c02218b3ae2b23b51056a0d36c3a48258ba87a08..6147770b43471be8b5fd721cde035af84aaf0184 100644 (file)
@@ -72,6 +72,26 @@ int get_maxlvt(void)
        return maxlvt;
 }
 
+/*
+ * 'what should we do if we get a hw irq event on an illegal vector'.
+ * each architecture has to answer this themselves.
+ */
+void ack_bad_irq(unsigned int irq)
+{
+       printk("unexpected IRQ trap at vector %02x\n", irq);
+       /*
+        * Currently unexpected vectors happen only on SMP and APIC.
+        * We _must_ ack these because every local APIC has only N
+        * irq slots per priority level, and a 'hanging, unacked' IRQ
+        * holds up an irq slot - in excessive cases (when multiple
+        * unexpected vectors occur) that might lock up the APIC
+        * completely.
+        * But don't ack when the APIC is disabled. -AK
+        */
+       if (!disable_apic)
+               ack_APIC_irq();
+}
+
 void clear_local_APIC(void)
 {
        int maxlvt;
index 8661b476fb404f74e14d4ed7342e92575c37c50d..8689951e350348be7123affa57241d77997eb41b 100644 (file)
 #define set_softirq_pending(x) write_pda(__softirq_pending, (x))
 #define or_softirq_pending(x)  or_pda(__softirq_pending, (x))
 
-/*
- * 'what should we do if we get a hw irq event on an illegal vector'.
- * each architecture has to answer this themselves.
- */
-static inline void ack_bad_irq(unsigned int irq)
-{
-       printk("unexpected IRQ trap at vector %02x\n", irq);
-#ifdef CONFIG_X86_LOCAL_APIC
-       /*
-        * Currently unexpected vectors happen only on SMP and APIC.
-        * We _must_ ack these because every local APIC has only N
-        * irq slots per priority level, and a 'hanging, unacked' IRQ
-        * holds up an irq slot - in excessive cases (when multiple
-        * unexpected vectors occur) that might lock up the APIC
-        * completely.
-        */
-       ack_APIC_irq();
-#endif
-}
+extern void ack_bad_irq(unsigned int irq);
+
 #endif /* __ASM_HARDIRQ_H */