[PATCH] MSI interrupts: disallow when no LAPIC/IOAPIC support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Randy Dunlap <[email protected]>

MSI requires local APIC + IO APIC support (according to
drivers/pci/Kconfig), but if a kernel is built with all of
those (APICs + CONFIG_PCI_MSI) and then booted with "nosmp" or
"max_cpus=0|1" or "noapic" or "nolapic", MSI also should be
disabled, otherwise the interrupt routing is bad (so that only
using "irqpoll" helps).

Signed-off-by: Randy Dunlap <[email protected]>
---

 arch/i386/kernel/io_apic.c   |    2 ++
 arch/i386/kernel/smpboot.c   |    6 +++++-
 arch/x86_64/kernel/apic.c    |    6 +++++-
 arch/x86_64/kernel/io_apic.c |    2 ++
 arch/x86_64/kernel/setup.c   |    4 +++-
 arch/x86_64/kernel/smpboot.c |   11 +++++++++--
 drivers/pci/msi.c            |    5 +++++
 include/linux/pci.h          |    2 ++
 8 files changed, 33 insertions(+), 5 deletions(-)

diff -Naurp -X linux-2614-rc2/Documentation/dontdiff linux-2614-rc2-git4-pv/arch/i386/kernel/io_apic.c linux-2614-rc2-git4/arch/i386/kernel/io_apic.c
--- linux-2614-rc2-git4-pv/arch/i386/kernel/io_apic.c	2005-09-25 13:18:08.000000000 -0700
+++ linux-2614-rc2-git4/arch/i386/kernel/io_apic.c	2005-09-25 14:54:45.000000000 -0700
@@ -31,6 +31,7 @@
 #include <linux/mc146818rtc.h>
 #include <linux/compiler.h>
 #include <linux/acpi.h>
+#include <linux/pci.h>
 #include <linux/module.h>
 #include <linux/sysdev.h>
 
@@ -684,6 +685,7 @@ int skip_ioapic_setup;
 static int __init ioapic_setup(char *str)
 {
 	skip_ioapic_setup = 1;
+	msi_off();
 	return 1;
 }
 
diff -Naurp -X linux-2614-rc2/Documentation/dontdiff linux-2614-rc2-git4-pv/arch/i386/kernel/smpboot.c linux-2614-rc2-git4/arch/i386/kernel/smpboot.c
--- linux-2614-rc2-git4-pv/arch/i386/kernel/smpboot.c	2005-09-25 13:18:08.000000000 -0700
+++ linux-2614-rc2-git4/arch/i386/kernel/smpboot.c	2005-09-25 14:54:51.000000000 -0700
@@ -46,6 +46,7 @@
 #include <linux/bootmem.h>
 #include <linux/notifier.h>
 #include <linux/cpu.h>
+#include <linux/pci.h>
 #include <linux/percpu.h>
 
 #include <linux/delay.h>
@@ -1107,9 +1108,11 @@ static void __init smp_boot_cpus(unsigne
 		printk(KERN_NOTICE "SMP motherboard not detected.\n");
 		smpboot_clear_io_apic_irqs();
 		phys_cpu_present_map = physid_mask_of_physid(0);
-		if (APIC_init_uniprocessor())
+		if (APIC_init_uniprocessor()) {
 			printk(KERN_NOTICE "Local APIC not detected."
 					   " Using dummy APIC emulation.\n");
+			msi_off();
+		}
 		map_cpu_to_logical_apicid();
 		cpu_set(0, cpu_sibling_map[0]);
 		cpu_set(0, cpu_core_map[0]);
@@ -1150,6 +1153,7 @@ static void __init smp_boot_cpus(unsigne
 		smp_found_config = 0;
 		printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
 		smpboot_clear_io_apic_irqs();
+		msi_off();
 		phys_cpu_present_map = physid_mask_of_physid(0);
 		cpu_set(0, cpu_sibling_map[0]);
 		cpu_set(0, cpu_core_map[0]);
diff -Naurp -X linux-2614-rc2/Documentation/dontdiff linux-2614-rc2-git4-pv/arch/x86_64/kernel/apic.c linux-2614-rc2-git4/arch/x86_64/kernel/apic.c
--- linux-2614-rc2-git4-pv/arch/x86_64/kernel/apic.c	2005-09-25 13:18:11.000000000 -0700
+++ linux-2614-rc2-git4/arch/x86_64/kernel/apic.c	2005-09-25 14:55:20.000000000 -0700
@@ -24,6 +24,7 @@
 #include <linux/interrupt.h>
 #include <linux/mc146818rtc.h>
 #include <linux/kernel_stat.h>
+#include <linux/pci.h>
 #include <linux/sysdev.h>
 
 #include <asm/atomic.h>
@@ -1057,8 +1058,10 @@ int __init APIC_init_uniprocessor (void)
 #ifdef CONFIG_X86_IO_APIC
 	if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
 			setup_IO_APIC();
-	else
+	else {
 		nr_ioapics = 0;
+		msi_off();
+	}
 #endif
 	setup_boot_APIC_clock();
 	check_nmi_watchdog();
@@ -1074,6 +1077,7 @@ static __init int setup_disableapic(char
 static __init int setup_nolapic(char *str) 
 { 
 	disable_apic = 1;
+	msi_off();
 	return 0;
 } 
 
diff -Naurp -X linux-2614-rc2/Documentation/dontdiff linux-2614-rc2-git4-pv/arch/x86_64/kernel/io_apic.c linux-2614-rc2-git4/arch/x86_64/kernel/io_apic.c
--- linux-2614-rc2-git4-pv/arch/x86_64/kernel/io_apic.c	2005-09-25 13:18:11.000000000 -0700
+++ linux-2614-rc2-git4/arch/x86_64/kernel/io_apic.c	2005-09-25 14:55:22.000000000 -0700
@@ -29,6 +29,7 @@
 #include <linux/smp_lock.h>
 #include <linux/mc146818rtc.h>
 #include <linux/acpi.h>
+#include <linux/pci.h>
 #include <linux/sysdev.h>
 
 #include <asm/io.h>
@@ -227,6 +228,7 @@ int ioapic_force;
 static int __init disable_ioapic_setup(char *str)
 {
 	skip_ioapic_setup = 1;
+	msi_off();
 	return 1;
 }
 
diff -Naurp -X linux-2614-rc2/Documentation/dontdiff linux-2614-rc2-git4-pv/arch/x86_64/kernel/setup.c linux-2614-rc2-git4/arch/x86_64/kernel/setup.c
--- linux-2614-rc2-git4-pv/arch/x86_64/kernel/setup.c	2005-09-25 13:18:11.000000000 -0700
+++ linux-2614-rc2-git4/arch/x86_64/kernel/setup.c	2005-09-25 14:55:27.000000000 -0700
@@ -345,8 +345,10 @@ static __init void parse_cmdline_early (
 		    !memcmp(from, "disableapic", 11))
 			disable_apic = 1;
 
-		if (!memcmp(from, "noapic", 6)) 
+		if (!memcmp(from, "noapic", 6)) {
 			skip_ioapic_setup = 1;
+			msi_off();
+		}
 
 		if (!memcmp(from, "apic", 4)) { 
 			skip_ioapic_setup = 0;
diff -Naurp -X linux-2614-rc2/Documentation/dontdiff linux-2614-rc2-git4-pv/arch/x86_64/kernel/smpboot.c linux-2614-rc2-git4/arch/x86_64/kernel/smpboot.c
--- linux-2614-rc2-git4-pv/arch/x86_64/kernel/smpboot.c	2005-09-25 13:18:11.000000000 -0700
+++ linux-2614-rc2-git4/arch/x86_64/kernel/smpboot.c	2005-09-25 14:55:33.000000000 -0700
@@ -47,6 +47,7 @@
 #include <linux/bootmem.h>
 #include <linux/thread_info.h>
 #include <linux/module.h>
+#include <linux/pci.h>
 
 #include <linux/delay.h>
 #include <linux/mc146818rtc.h>
@@ -918,9 +919,11 @@ static int __init smp_sanity_check(unsig
 	if (!smp_found_config) {
 		printk(KERN_NOTICE "SMP motherboard not detected.\n");
 		disable_smp();
-		if (APIC_init_uniprocessor())
+		if (APIC_init_uniprocessor()) {
 			printk(KERN_NOTICE "Local APIC not detected."
 					   " Using dummy APIC emulation.\n");
+			msi_off();
+		}
 		return -1;
 	}
 
@@ -942,6 +945,7 @@ static int __init smp_sanity_check(unsig
 			boot_cpu_id);
 		printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
 		nr_ioapics = 0;
+		msi_off();
 		return -1;
 	}
 
@@ -951,6 +955,7 @@ static int __init smp_sanity_check(unsig
 	if (!max_cpus) {
 		printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
 		nr_ioapics = 0;
+		msi_off();
 		return -1;
 	}
 
@@ -995,8 +1000,10 @@ void __init smp_prepare_cpus(unsigned in
 	 */
 	if (!skip_ioapic_setup && nr_ioapics)
 		setup_IO_APIC();
-	else
+	else {
 		nr_ioapics = 0;
+		msi_off();
+	}
 
 	/*
 	 * Set up local APIC timer on boot CPU.
diff -Naurp -X linux-2614-rc2/Documentation/dontdiff linux-2614-rc2-git4-pv/drivers/pci/msi.c linux-2614-rc2-git4/drivers/pci/msi.c
--- linux-2614-rc2-git4-pv/drivers/pci/msi.c	2005-09-25 13:18:14.000000000 -0700
+++ linux-2614-rc2-git4/drivers/pci/msi.c	2005-09-25 14:53:53.000000000 -0700
@@ -1113,6 +1113,11 @@ void msi_remove_pci_irq_vectors(struct p
 	}
 }
 
+void msi_off(void)
+{
+	pci_msi_enable = 0;
+}
+
 EXPORT_SYMBOL(pci_enable_msi);
 EXPORT_SYMBOL(pci_disable_msi);
 EXPORT_SYMBOL(pci_enable_msix);
diff -Naurp -X linux-2614-rc2/Documentation/dontdiff linux-2614-rc2-git4-pv/include/linux/pci.h linux-2614-rc2-git4/include/linux/pci.h
--- linux-2614-rc2-git4-pv/include/linux/pci.h	2005-09-25 13:18:20.000000000 -0700
+++ linux-2614-rc2-git4/include/linux/pci.h	2005-09-25 14:53:27.000000000 -0700
@@ -480,6 +480,7 @@ static inline int pci_enable_msix(struct
 	struct msix_entry *entries, int nvec) {return -1;}
 static inline void pci_disable_msix(struct pci_dev *dev) {}
 static inline void msi_remove_pci_irq_vectors(struct pci_dev *dev) {}
+static inline void msi_off(void) {}
 #else
 extern void pci_scan_msi_device(struct pci_dev *dev);
 extern int pci_enable_msi(struct pci_dev *dev);
@@ -488,6 +489,7 @@ extern int pci_enable_msix(struct pci_de
 	struct msix_entry *entries, int nvec);
 extern void pci_disable_msix(struct pci_dev *dev);
 extern void msi_remove_pci_irq_vectors(struct pci_dev *dev);
+extern void msi_off(void);
 #endif
 
 /*


---
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]
  Powered by Linux