Commit 0637a70a5db98182d9ad3d6ae1ee30acf20afde9
Committed by
Andi Kleen
1 parent
8f60774a11
Exists in
master
and in
4 other branches
[PATCH] x86: Allow disabling early pci scans with pci=noearly or disallowing conf1
Some buggy systems can machine check when config space accesses happen for some non existent devices. i386/x86-64 do some early device scans that might trigger this. Allow pci=noearly to disable this. Also when type 1 is disabling also don't do any early accesses which are always type1. This moves the pci= configuration parsing to be a early parameter. I don't think this can break anything because it only changes a single global that is only used by PCI. Cc: gregkh@suse.de Cc: Trammell Hudson <hudson@osresearch.net> Signed-off-by: Andi Kleen <ak@suse.de>
Showing 12 changed files with 41 additions and 6 deletions Side-by-side Diff
- Documentation/kernel-parameters.txt
- arch/i386/kernel/acpi/earlyquirk.c
- arch/i386/pci/common.c
- arch/i386/pci/early.c
- arch/i386/pci/pci.h
- arch/x86_64/kernel/aperture.c
- arch/x86_64/kernel/early-quirks.c
- arch/x86_64/kernel/pci-calgary.c
- arch/x86_64/kernel/vsmp.c
- arch/x86_64/mm/k8topology.c
- drivers/pci/pci.c
- include/asm-x86_64/pci-direct.h
Documentation/kernel-parameters.txt
... | ... | @@ -1240,7 +1240,11 @@ |
1240 | 1240 | bootloader. This is currently used on |
1241 | 1241 | IXP2000 systems where the bus has to be |
1242 | 1242 | configured a certain way for adjunct CPUs. |
1243 | - | |
1243 | + noearly [X86] Don't do any early type 1 scanning. | |
1244 | + This might help on some broken boards which | |
1245 | + machine check when some devices' config space | |
1246 | + is read. But various workarounds are disabled | |
1247 | + and some IOMMU drivers will not work. | |
1244 | 1248 | pcmv= [HW,PCMCIA] BadgePAD 4 |
1245 | 1249 | |
1246 | 1250 | pd. [PARIDE] |
arch/i386/kernel/acpi/earlyquirk.c
... | ... | @@ -48,7 +48,11 @@ |
48 | 48 | int num, slot, func; |
49 | 49 | |
50 | 50 | /* Assume the machine supports type 1. If not it will |
51 | - always read ffffffff and should not have any side effect. */ | |
51 | + always read ffffffff and should not have any side effect. | |
52 | + Actually a few buggy systems can machine check. Allow the user | |
53 | + to disable it by command line option at least -AK */ | |
54 | + if (!early_pci_allowed()) | |
55 | + return; | |
52 | 56 | |
53 | 57 | /* Poor man's PCI discovery */ |
54 | 58 | for (num = 0; num < 32; num++) { |
arch/i386/pci/common.c
... | ... | @@ -242,6 +242,10 @@ |
242 | 242 | acpi_noirq_set(); |
243 | 243 | return NULL; |
244 | 244 | } |
245 | + else if (!strcmp(str, "noearly")) { | |
246 | + pci_probe |= PCI_PROBE_NOEARLY; | |
247 | + return NULL; | |
248 | + } | |
245 | 249 | #ifndef CONFIG_X86_VISWS |
246 | 250 | else if (!strcmp(str, "usepirqmask")) { |
247 | 251 | pci_probe |= PCI_USE_PIRQ_MASK; |
arch/i386/pci/early.c
1 | 1 | #include <linux/kernel.h> |
2 | +#include <linux/pci.h> | |
2 | 3 | #include <asm/pci-direct.h> |
3 | 4 | #include <asm/io.h> |
5 | +#include "pci.h" | |
4 | 6 | |
5 | 7 | /* Direct PCI access. This is used for PCI accesses in early boot before |
6 | 8 | the PCI subsystem works. */ |
... | ... | @@ -41,5 +43,11 @@ |
41 | 43 | PDprintk("%x writing to %x: %x\n", slot, offset, val); |
42 | 44 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); |
43 | 45 | outl(val, 0xcfc); |
46 | +} | |
47 | + | |
48 | +int early_pci_allowed(void) | |
49 | +{ | |
50 | + return (pci_probe & (PCI_PROBE_CONF1|PCI_PROBE_NOEARLY)) == | |
51 | + PCI_PROBE_CONF1; | |
44 | 52 | } |
arch/i386/pci/pci.h
arch/x86_64/kernel/aperture.c
arch/x86_64/kernel/early-quirks.c
arch/x86_64/kernel/pci-calgary.c
arch/x86_64/kernel/vsmp.c
... | ... | @@ -20,6 +20,9 @@ |
20 | 20 | void *address; |
21 | 21 | unsigned int cap, ctl; |
22 | 22 | |
23 | + if (!early_pci_allowed()) | |
24 | + return 0; | |
25 | + | |
23 | 26 | /* Check if we are running on a ScaleMP vSMP box */ |
24 | 27 | if ((read_pci_config_16(0, 0x1f, 0, PCI_VENDOR_ID) != PCI_VENDOR_ID_SCALEMP) || |
25 | 28 | (read_pci_config_16(0, 0x1f, 0, PCI_DEVICE_ID) != PCI_DEVICE_ID_SCALEMP_VSMP_CTL)) |
arch/x86_64/mm/k8topology.c
drivers/pci/pci.c
... | ... | @@ -953,12 +953,11 @@ |
953 | 953 | } |
954 | 954 | str = k; |
955 | 955 | } |
956 | - return 1; | |
956 | + return 0; | |
957 | 957 | } |
958 | +early_param("pci", pci_setup); | |
958 | 959 | |
959 | 960 | device_initcall(pci_init); |
960 | - | |
961 | -__setup("pci=", pci_setup); | |
962 | 961 | |
963 | 962 | #if defined(CONFIG_ISA) || defined(CONFIG_EISA) |
964 | 963 | /* FIXME: Some boxes have multiple ISA bridges! */ |
include/asm-x86_64/pci-direct.h