diff options
author | Andi Kleen <ak@suse.de> | 2006-08-30 13:37:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-08-30 19:05:16 -0400 |
commit | 40dd2d20f220eda1cd0da8ea3f0f9db8971ba237 (patch) | |
tree | aea5d128ef6ce5bc16f18502f4d6745268344731 /arch | |
parent | 8c74932779fc6f61b4c30145863a17125c1a296c (diff) |
[PATCH] x86: Disable MMCONFIG on Intel SDV using DMI blacklist
As a replacement for the earlier removal of the e820 MCFG check
we blacklist the Intel SDV with the original BIOS bug that
motivated that check. On those machines don't use MMCONFIG.
This also adds a new pci=mmconf parameter to override the blacklist.
Cc: Greg KH <gregkh@suse.de>
Cc: Arjan van de Ven <arjan@infradead.org>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/pci/common.c | 5 | ||||
-rw-r--r-- | arch/i386/pci/mmconfig.c | 25 | ||||
-rw-r--r-- | arch/i386/pci/pci.h | 3 | ||||
-rw-r--r-- | arch/x86_64/pci/mmconfig.c | 25 |
4 files changed, 55 insertions, 3 deletions
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 0a362e3aeac5..1220dd828ce3 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c | |||
@@ -237,6 +237,11 @@ char * __devinit pcibios_setup(char *str) | |||
237 | pci_probe &= ~PCI_PROBE_MMCONF; | 237 | pci_probe &= ~PCI_PROBE_MMCONF; |
238 | return NULL; | 238 | return NULL; |
239 | } | 239 | } |
240 | /* override DMI blacklist */ | ||
241 | else if (!strcmp(str, "mmconf")) { | ||
242 | pci_probe |= PCI_PROBE_MMCONF_FORCE; | ||
243 | return NULL; | ||
244 | } | ||
240 | #endif | 245 | #endif |
241 | else if (!strcmp(str, "noacpi")) { | 246 | else if (!strcmp(str, "noacpi")) { |
242 | acpi_noirq_set(); | 247 | acpi_noirq_set(); |
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 5effb2e663ed..ef5a2faa7d82 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/pci.h> | 12 | #include <linux/pci.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/acpi.h> | 14 | #include <linux/acpi.h> |
15 | #include <linux/dmi.h> | ||
15 | #include <asm/e820.h> | 16 | #include <asm/e820.h> |
16 | #include "pci.h" | 17 | #include "pci.h" |
17 | 18 | ||
@@ -187,9 +188,31 @@ static __init void unreachable_devices(void) | |||
187 | } | 188 | } |
188 | } | 189 | } |
189 | 190 | ||
191 | static int disable_mcfg(struct dmi_system_id *d) | ||
192 | { | ||
193 | printk("PCI: %s detected. Disabling MCFG.\n", d->ident); | ||
194 | pci_probe &= ~PCI_PROBE_MMCONF; | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static struct dmi_system_id __initdata dmi_bad_mcfg[] = { | ||
199 | /* Has broken MCFG table that makes the system hang when used */ | ||
200 | { | ||
201 | .callback = disable_mcfg, | ||
202 | .ident = "Intel D3C5105 SDV", | ||
203 | .matches = { | ||
204 | DMI_MATCH(DMI_BIOS_VENDOR, "Intel"), | ||
205 | DMI_MATCH(DMI_BOARD_NAME, "D26928"), | ||
206 | }, | ||
207 | }, | ||
208 | {} | ||
209 | }; | ||
210 | |||
190 | void __init pci_mmcfg_init(void) | 211 | void __init pci_mmcfg_init(void) |
191 | { | 212 | { |
192 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) | 213 | dmi_check_system(dmi_bad_mcfg); |
214 | |||
215 | if ((pci_probe & (PCI_PROBE_MMCONF_FORCE|PCI_PROBE_MMCONF)) == 0) | ||
193 | return; | 216 | return; |
194 | 217 | ||
195 | acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); | 218 | acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); |
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index bf4e79335388..49a849b3a241 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h | |||
@@ -16,7 +16,8 @@ | |||
16 | #define PCI_PROBE_CONF1 0x0002 | 16 | #define PCI_PROBE_CONF1 0x0002 |
17 | #define PCI_PROBE_CONF2 0x0004 | 17 | #define PCI_PROBE_CONF2 0x0004 |
18 | #define PCI_PROBE_MMCONF 0x0008 | 18 | #define PCI_PROBE_MMCONF 0x0008 |
19 | #define PCI_PROBE_MASK 0x000f | 19 | #define PCI_PROBE_MMCONF_FORCE 0x0010 |
20 | #define PCI_PROBE_MASK 0x00ff | ||
20 | 21 | ||
21 | #define PCI_NO_SORT 0x0100 | 22 | #define PCI_NO_SORT 0x0100 |
22 | #define PCI_BIOS_SORT 0x0200 | 23 | #define PCI_BIOS_SORT 0x0200 |
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index 8a4a0f9263ce..2d48a7941d48 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/acpi.h> | 10 | #include <linux/acpi.h> |
11 | #include <linux/bitmap.h> | 11 | #include <linux/bitmap.h> |
12 | #include <linux/dmi.h> | ||
12 | #include <asm/e820.h> | 13 | #include <asm/e820.h> |
13 | 14 | ||
14 | #include "pci.h" | 15 | #include "pci.h" |
@@ -164,11 +165,33 @@ static __init void unreachable_devices(void) | |||
164 | } | 165 | } |
165 | } | 166 | } |
166 | 167 | ||
168 | static int disable_mcfg(struct dmi_system_id *d) | ||
169 | { | ||
170 | printk("PCI: %s detected. Disabling MCFG.\n", d->ident); | ||
171 | pci_probe &= ~PCI_PROBE_MMCONF; | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static struct dmi_system_id __initdata dmi_bad_mcfg[] = { | ||
176 | /* Has broken MCFG table that makes the system hang when used */ | ||
177 | { | ||
178 | .callback = disable_mcfg, | ||
179 | .ident = "Intel D3C5105 SDV", | ||
180 | .matches = { | ||
181 | DMI_MATCH(DMI_BIOS_VENDOR, "Intel"), | ||
182 | DMI_MATCH(DMI_BOARD_NAME, "D26928"), | ||
183 | }, | ||
184 | }, | ||
185 | {} | ||
186 | }; | ||
187 | |||
167 | void __init pci_mmcfg_init(void) | 188 | void __init pci_mmcfg_init(void) |
168 | { | 189 | { |
169 | int i; | 190 | int i; |
170 | 191 | ||
171 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) | 192 | dmi_check_system(dmi_bad_mcfg); |
193 | |||
194 | if ((pci_probe & (PCI_PROBE_MMCONF|PCI_PROBE_MMCONF_FORCE)) == 0) | ||
172 | return; | 195 | return; |
173 | 196 | ||
174 | acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); | 197 | acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); |