浏览代码

x86, pci: introduce pci=ioapicreroute kernel cmdline option

Introduce pci=ioapicreroute kernel cmdline option to enable rerouting of boot
interrupts to the primary io-apic.

Signed-off-by: Stefan Assmann <sassmann@suse.de>
Signed-off-by: Olaf Dabrunz <od@suse.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Stefan Assmann 17 年之前
父节点
当前提交
9197979b51
共有 4 个文件被更改,包括 14 次插入0 次删除
  1. 4 0
      Documentation/kernel-parameters.txt
  2. 5 0
      arch/x86/pci/common.c
  3. 4 0
      include/asm-x86/io_apic.h
  4. 1 0
      include/asm-x86/pci.h

+ 4 - 0
Documentation/kernel-parameters.txt

@@ -1521,6 +1521,10 @@ and is between 256 and 4096 characters. It is defined in the file
 		noioapicquirk	[APIC] Disable all boot interrupt quirks.
 		noioapicquirk	[APIC] Disable all boot interrupt quirks.
 				Safety option to keep boot IRQs enabled. This
 				Safety option to keep boot IRQs enabled. This
 				should never be necessary.
 				should never be necessary.
+		ioapicreroute	[APIC] Enable rerouting of boot IRQs to the
+				primary IO-APIC for bridges that cannot disable
+				boot IRQs. This fixes a source of spurious IRQs
+				when the system masks IRQs.
 		biosirq		[X86-32] Use PCI BIOS calls to get the interrupt
 		biosirq		[X86-32] Use PCI BIOS calls to get the interrupt
 				routing table. These calls are known to be buggy
 				routing table. These calls are known to be buggy
 				on several machines and they hang the machine
 				on several machines and they hang the machine

+ 5 - 0
arch/x86/pci/common.c

@@ -23,6 +23,7 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
 static int pci_bf_sort;
 static int pci_bf_sort;
 int pci_routeirq;
 int pci_routeirq;
 int noioapicquirk;
 int noioapicquirk;
+int noioapicreroute = 1;
 int pcibios_last_bus = -1;
 int pcibios_last_bus = -1;
 unsigned long pirq_table_addr;
 unsigned long pirq_table_addr;
 struct pci_bus *pci_root_bus;
 struct pci_bus *pci_root_bus;
@@ -499,6 +500,10 @@ char * __devinit  pcibios_setup(char *str)
 	} else if (!strcmp(str, "noioapicquirk")) {
 	} else if (!strcmp(str, "noioapicquirk")) {
 		noioapicquirk = 1;
 		noioapicquirk = 1;
 		return NULL;
 		return NULL;
+	} else if (!strcmp(str, "ioapicreroute")) {
+		if (noioapicreroute != -1)
+			noioapicreroute = 0;
+		return NULL;
 	}
 	}
 	return str;
 	return str;
 }
 }

+ 4 - 0
include/asm-x86/io_apic.h

@@ -160,12 +160,16 @@ extern int skip_ioapic_setup;
 /* 1 if "noapic" boot option passed */
 /* 1 if "noapic" boot option passed */
 extern int noioapicquirk;
 extern int noioapicquirk;
 
 
+/* -1 if "noapic" boot option passed */
+extern int noioapicreroute;
+
 /* 1 if the timer IRQ uses the '8259A Virtual Wire' mode */
 /* 1 if the timer IRQ uses the '8259A Virtual Wire' mode */
 extern int timer_through_8259;
 extern int timer_through_8259;
 
 
 static inline void disable_ioapic_setup(void)
 static inline void disable_ioapic_setup(void)
 {
 {
 	noioapicquirk = 1;
 	noioapicquirk = 1;
+	noioapicreroute = -1;
 	skip_ioapic_setup = 1;
 	skip_ioapic_setup = 1;
 }
 }
 
 

+ 1 - 0
include/asm-x86/pci.h

@@ -20,6 +20,7 @@ struct pci_sysdata {
 
 
 extern int pci_routeirq;
 extern int pci_routeirq;
 extern int noioapicquirk;
 extern int noioapicquirk;
+extern int ioapicreroute;
 
 
 /* scan a bus after allocating a pci_sysdata for it */
 /* scan a bus after allocating a pci_sysdata for it */
 extern struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops,
 extern struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops,