]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Stefan Assmann <sassmann@suse.de> |
2 | Subject: Introduce config option for pci reroute quirks | |
3 | ||
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. | |
10 | ||
11 | This means that the reroute quirk can be applied to any kernel without | |
12 | changing it. | |
13 | ||
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. | |
17 | ||
18 | The option can be overridden by either pci=ioapicreroute or | |
19 | pci=noioapicreroute. | |
20 | ||
21 | Signed-off-by: Stefan Assmann <sassmann@suse.de> | |
22 | Signed-off-by: Olaf Dabrunz <od@suse.de> | |
23 | --- | |
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(-) | |
30 | ||
31 | --- a/arch/x86/Kconfig | |
32 | +++ b/arch/x86/Kconfig | |
33 | @@ -624,6 +624,30 @@ config SCHED_MC | |
34 | ||
35 | source "kernel/Kconfig.preempt" | |
36 | ||
37 | +config X86_REROUTE_FOR_BROKEN_BOOT_IRQS | |
38 | + bool "Reroute for broken boot IRQs" | |
39 | + default n | |
40 | + depends on X86_IO_APIC | |
41 | + help | |
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. | |
46 | + | |
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. | |
57 | + | |
58 | + Only affects "broken" chipsets. Interrupt sharing may be | |
59 | + increased on these systems. | |
60 | + | |
61 | config X86_UP_APIC | |
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; | |
68 | int pci_routeirq; | |
69 | int noioapicquirk; | |
70 | +#ifdef CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS | |
71 | +int noioapicreroute = 0; | |
72 | +#else | |
73 | int noioapicreroute = 1; | |
74 | +#endif | |
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) | |
80 | noioapicreroute = 0; | |
81 | return NULL; | |
82 | + } else if (!strcmp(str, "noioapicreroute")) { | |
83 | + if (noioapicreroute != -1) | |
84 | + noioapicreroute = 1; | |
85 | + return NULL; | |
86 | } | |
87 | return str; | |
88 | } | |
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 | |
105 | */ | |
106 | static void quirk_reroute_to_boot_interrupts_intel(struct pci_dev *dev) | |
107 | { | |
108 | - if (noioapicquirk) | |
109 | + if (noioapicquirk || noioapicreroute) | |
110 | return; | |
111 | ||
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 { | |
116 | ||
117 | extern int pci_routeirq; | |
118 | extern int noioapicquirk; | |
119 | -extern int ioapicreroute; | |
120 | +extern int noioapicreroute; | |
121 | ||
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, |