1 From: Stefan Assmann <sassmann@suse.de>
2 Subject: Introduce config option for pci reroute quirks
4 The config option X86_REROUTE_FOR_BROKEN_BOOT_IRQS is introduced to
5 enable (or disable) the redirection of the interrupt handler to the boot
6 interrupt line by default. Depending on the existence of interrupt
7 masking / threaded interrupt handling in the kernel (vanilla, rt, ...)
8 and the maturity of the rerouting patch, users can enable or disable the
9 redirection by default.
11 This means that the reroute quirk can be applied to any kernel without
14 Interrupt sharing could be increased if this option is enabled. However this
15 option is vital for threaded interrupt handling, as done by the RT kernel.
16 It should simplify the consolidation with the RT kernel.
18 The option can be overridden by either pci=ioapicreroute or
21 Signed-off-by: Stefan Assmann <sassmann@suse.de>
22 Signed-off-by: Olaf Dabrunz <od@suse.de>
24 Documentation/kernel-parameters.txt | 4 ++++
25 arch/x86/Kconfig | 24 ++++++++++++++++++++++++
26 arch/x86/pci/common.c | 8 ++++++++
27 drivers/pci/quirks.c | 2 +-
28 include/asm-x86/pci.h | 2 +-
29 5 files changed, 38 insertions(+), 2 deletions(-)
31 --- a/arch/x86/Kconfig
32 +++ b/arch/x86/Kconfig
33 @@ -624,6 +624,30 @@ config SCHED_MC
35 source "kernel/Kconfig.preempt"
37 +config X86_REROUTE_FOR_BROKEN_BOOT_IRQS
38 + bool "Reroute for broken boot IRQs"
40 + depends on X86_IO_APIC
42 + This option enables a workaround that fixes a source of
43 + spurious interrupts. This is recommended when threaded
44 + interrupt handling is used on systems where the generation of
45 + superfluous "boot interrupts" cannot be disabled.
47 + Some chipsets generate a legacy INTx "boot IRQ" when the IRQ
48 + entry in the chipset's IO-APIC is masked (as, e.g. the RT
49 + kernel does during interrupt handling). On chipsets where this
50 + boot IRQ generation cannot be disabled, this workaround keeps
51 + the original IRQ line masked so that only the equivalent "boot
52 + IRQ" is delivered to the CPUs. The workaround also tells the
53 + kernel to set up the IRQ handler on the boot IRQ line. In this
54 + way only one interrupt is delivered to the kernel. Otherwise
55 + the spurious second interrupt may cause the kernel to bring
56 + down (vital) interrupt lines.
58 + Only affects "broken" chipsets. Interrupt sharing may be
59 + increased on these systems.
62 bool "Local APIC support on uniprocessors"
63 depends on X86_32 && !SMP && !(X86_VOYAGER || X86_GENERICARCH)
64 --- a/arch/x86/pci/common.c
65 +++ b/arch/x86/pci/common.c
66 @@ -24,7 +24,11 @@ unsigned int pci_early_dump_regs;
67 static int pci_bf_sort;
70 +#ifdef CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS
71 +int noioapicreroute = 0;
73 int noioapicreroute = 1;
75 int pcibios_last_bus = -1;
76 unsigned long pirq_table_addr;
77 struct pci_bus *pci_root_bus;
78 @@ -528,6 +532,10 @@ char * __devinit pcibios_setup(char *st
79 if (noioapicreroute != -1)
82 + } else if (!strcmp(str, "noioapicreroute")) {
83 + if (noioapicreroute != -1)
84 + noioapicreroute = 1;
89 --- a/Documentation/kernel-parameters.txt
90 +++ b/Documentation/kernel-parameters.txt
91 @@ -1573,6 +1573,10 @@ and is between 256 and 4096 characters.
92 primary IO-APIC for bridges that cannot disable
93 boot IRQs. This fixes a source of spurious IRQs
94 when the system masks IRQs.
95 + noioapicreroute [APIC] Disable workaround that uses the
96 + boot IRQ equivalent of an IRQ that connects to
97 + a chipset where boot IRQs cannot be disabled.
98 + The opposite of ioapicreroute.
99 biosirq [X86-32] Use PCI BIOS calls to get the interrupt
100 routing table. These calls are known to be buggy
101 on several machines and they hang the machine
102 --- a/drivers/pci/quirks.c
103 +++ b/drivers/pci/quirks.c
104 @@ -1411,7 +1411,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IN
106 static void quirk_reroute_to_boot_interrupts_intel(struct pci_dev *dev)
109 + if (noioapicquirk || noioapicreroute)
112 dev->irq_reroute_variant = INTEL_IRQ_REROUTE_VARIANT;
113 --- a/include/asm-x86/pci.h
114 +++ b/include/asm-x86/pci.h
115 @@ -20,7 +20,7 @@ struct pci_sysdata {
117 extern int pci_routeirq;
118 extern int noioapicquirk;
119 -extern int ioapicreroute;
120 +extern int noioapicreroute;
122 /* scan a bus after allocating a pci_sysdata for it */
123 extern struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops,