diff options
| -rw-r--r-- | Documentation/kernel-parameters.txt | 4 | ||||
| -rw-r--r-- | arch/x86/Kconfig | 24 | ||||
| -rw-r--r-- | arch/x86/pci/common.c | 8 | ||||
| -rw-r--r-- | drivers/pci/quirks.c | 2 | ||||
| -rw-r--r-- | include/asm-x86/pci.h | 2 |
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 | |||
| 1536 | primary IO-APIC for bridges that cannot disable | 1536 | primary IO-APIC for bridges that cannot disable |
| 1537 | boot IRQs. This fixes a source of spurious IRQs | 1537 | boot IRQs. This fixes a source of spurious IRQs |
| 1538 | when the system masks IRQs. | 1538 | when the system masks IRQs. |
| 1539 | noioapicreroute [APIC] Disable workaround that uses the | ||
| 1540 | boot IRQ equivalent of an IRQ that connects to | ||
| 1541 | a chipset where boot IRQs cannot be disabled. | ||
| 1542 | The opposite of ioapicreroute. | ||
| 1539 | biosirq [X86-32] Use PCI BIOS calls to get the interrupt | 1543 | biosirq [X86-32] Use PCI BIOS calls to get the interrupt |
| 1540 | routing table. These calls are known to be buggy | 1544 | routing table. These calls are known to be buggy |
| 1541 | on several machines and they hang the machine | 1545 | 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 | |||
| 665 | def_bool y | 665 | def_bool y |
| 666 | depends on X86_32 && X86_VISWS | 666 | depends on X86_32 && X86_VISWS |
| 667 | 667 | ||
| 668 | config X86_REROUTE_FOR_BROKEN_BOOT_IRQS | ||
| 669 | bool "Reroute for broken boot IRQs" | ||
| 670 | default n | ||
| 671 | depends on X86_IO_APIC | ||
| 672 | help | ||
| 673 | This option enables a workaround that fixes a source of | ||
| 674 | spurious interrupts. This is recommended when threaded | ||
| 675 | interrupt handling is used on systems where the generation of | ||
| 676 | superfluous "boot interrupts" cannot be disabled. | ||
| 677 | |||
| 678 | Some chipsets generate a legacy INTx "boot IRQ" when the IRQ | ||
| 679 | entry in the chipset's IO-APIC is masked (as, e.g. the RT | ||
| 680 | kernel does during interrupt handling). On chipsets where this | ||
| 681 | boot IRQ generation cannot be disabled, this workaround keeps | ||
| 682 | the original IRQ line masked so that only the equivalent "boot | ||
| 683 | IRQ" is delivered to the CPUs. The workaround also tells the | ||
| 684 | kernel to set up the IRQ handler on the boot IRQ line. In this | ||
| 685 | way only one interrupt is delivered to the kernel. Otherwise | ||
| 686 | the spurious second interrupt may cause the kernel to bring | ||
| 687 | down (vital) interrupt lines. | ||
| 688 | |||
| 689 | Only affects "broken" chipsets. Interrupt sharing may be | ||
| 690 | increased on these systems. | ||
| 691 | |||
| 668 | config X86_MCE | 692 | config X86_MCE |
| 669 | bool "Machine Check Exception" | 693 | bool "Machine Check Exception" |
| 670 | depends on !X86_VOYAGER | 694 | 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; | |||
| 24 | static int pci_bf_sort; | 24 | static int pci_bf_sort; |
| 25 | int pci_routeirq; | 25 | int pci_routeirq; |
| 26 | int noioapicquirk; | 26 | int noioapicquirk; |
| 27 | #ifdef CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS | ||
| 28 | int noioapicreroute = 0; | ||
| 29 | #else | ||
| 27 | int noioapicreroute = 1; | 30 | int noioapicreroute = 1; |
| 31 | #endif | ||
| 28 | int pcibios_last_bus = -1; | 32 | int pcibios_last_bus = -1; |
| 29 | unsigned long pirq_table_addr; | 33 | unsigned long pirq_table_addr; |
| 30 | struct pci_bus *pci_root_bus; | 34 | struct pci_bus *pci_root_bus; |
| @@ -528,6 +532,10 @@ char * __devinit pcibios_setup(char *str) | |||
| 528 | if (noioapicreroute != -1) | 532 | if (noioapicreroute != -1) |
| 529 | noioapicreroute = 0; | 533 | noioapicreroute = 0; |
| 530 | return NULL; | 534 | return NULL; |
| 535 | } else if (!strcmp(str, "noioapicreroute")) { | ||
| 536 | if (noioapicreroute != -1) | ||
| 537 | noioapicreroute = 1; | ||
| 538 | return NULL; | ||
| 531 | } | 539 | } |
| 532 | return str; | 540 | return str; |
| 533 | } | 541 | } |
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); | |||
| 1397 | */ | 1397 | */ |
| 1398 | static void quirk_reroute_to_boot_interrupts_intel(struct pci_dev *dev) | 1398 | static void quirk_reroute_to_boot_interrupts_intel(struct pci_dev *dev) |
| 1399 | { | 1399 | { |
| 1400 | if (noioapicquirk) | 1400 | if (noioapicquirk || noioapicreroute) |
| 1401 | return; | 1401 | return; |
| 1402 | 1402 | ||
| 1403 | dev->irq_reroute_variant = INTEL_IRQ_REROUTE_VARIANT; | 1403 | 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 { | |||
| 20 | 20 | ||
| 21 | extern int pci_routeirq; | 21 | extern int pci_routeirq; |
| 22 | extern int noioapicquirk; | 22 | extern int noioapicquirk; |
| 23 | extern int ioapicreroute; | 23 | extern int noioapicreroute; |
| 24 | 24 | ||
| 25 | /* scan a bus after allocating a pci_sysdata for it */ | 25 | /* scan a bus after allocating a pci_sysdata for it */ |
| 26 | extern struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops, | 26 | extern struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops, |
