summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt4
-rw-r--r--arch/x86/Kconfig24
-rw-r--r--arch/x86/pci/common.c8
-rw-r--r--drivers/pci/quirks.c2
-rw-r--r--include/asm-x86/pci.h2
5 files changed, 38 insertions, 2 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index f5662b7a34d1..62b6e8067a5b 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1536,6 +1536,10 @@ and is between 256 and 4096 characters. It is defined in the file
primary IO-APIC for bridges that cannot disable
boot IRQs. This fixes a source of spurious IRQs
when the system masks IRQs.
+ noioapicreroute [APIC] Disable workaround that uses the
+ boot IRQ equivalent of an IRQ that connects to
+ a chipset where boot IRQs cannot be disabled.
+ The opposite of ioapicreroute.
biosirq [X86-32] Use PCI BIOS calls to get the interrupt
routing table. These calls are known to be buggy
on several machines and they hang the machine
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 96e0c2ebc388..09521332636b 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -665,6 +665,30 @@ config X86_VISWS_APIC
def_bool y
depends on X86_32 && X86_VISWS
+config X86_REROUTE_FOR_BROKEN_BOOT_IRQS
+ bool "Reroute for broken boot IRQs"
+ default n
+ depends on X86_IO_APIC
+ help
+ This option enables a workaround that fixes a source of
+ spurious interrupts. This is recommended when threaded
+ interrupt handling is used on systems where the generation of
+ superfluous "boot interrupts" cannot be disabled.
+
+ Some chipsets generate a legacy INTx "boot IRQ" when the IRQ
+ entry in the chipset's IO-APIC is masked (as, e.g. the RT
+ kernel does during interrupt handling). On chipsets where this
+ boot IRQ generation cannot be disabled, this workaround keeps
+ the original IRQ line masked so that only the equivalent "boot
+ IRQ" is delivered to the CPUs. The workaround also tells the
+ kernel to set up the IRQ handler on the boot IRQ line. In this
+ way only one interrupt is delivered to the kernel. Otherwise
+ the spurious second interrupt may cause the kernel to bring
+ down (vital) interrupt lines.
+
+ Only affects "broken" chipsets. Interrupt sharing may be
+ increased on these systems.
+
config X86_MCE
bool "Machine Check Exception"
depends on !X86_VOYAGER
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 1485a26ddcef..bb1a01f089e2 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -24,7 +24,11 @@ unsigned int pci_early_dump_regs;
static int pci_bf_sort;
int pci_routeirq;
int noioapicquirk;
+#ifdef CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS
+int noioapicreroute = 0;
+#else
int noioapicreroute = 1;
+#endif
int pcibios_last_bus = -1;
unsigned long pirq_table_addr;
struct pci_bus *pci_root_bus;
@@ -528,6 +532,10 @@ char * __devinit pcibios_setup(char *str)
if (noioapicreroute != -1)
noioapicreroute = 0;
return NULL;
+ } else if (!strcmp(str, "noioapicreroute")) {
+ if (noioapicreroute != -1)
+ noioapicreroute = 1;
+ return NULL;
}
return str;
}
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 0911b0c60b64..c880dd0bbfb5 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1397,7 +1397,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260b, quirk_intel_pcie_pm);
*/
static void quirk_reroute_to_boot_interrupts_intel(struct pci_dev *dev)
{
- if (noioapicquirk)
+ if (noioapicquirk || noioapicreroute)
return;
dev->irq_reroute_variant = INTEL_IRQ_REROUTE_VARIANT;
diff --git a/include/asm-x86/pci.h b/include/asm-x86/pci.h
index 52a29f7668ef..9584d6d5eb93 100644
--- a/include/asm-x86/pci.h
+++ b/include/asm-x86/pci.h
@@ -20,7 +20,7 @@ struct pci_sysdata {
extern int pci_routeirq;
extern int noioapicquirk;
-extern int ioapicreroute;
+extern int noioapicreroute;
/* 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,