[PATCH] x86: Disable MMCONFIG on Intel SDV using DMI blacklist
authorAndi Kleen <ak@suse.de>
Wed, 30 Aug 2006 17:37:15 +0000 (19:37 +0200)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 30 Aug 2006 23:05:16 +0000 (16:05 -0700)
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>
Documentation/kernel-parameters.txt
arch/i386/pci/common.c
arch/i386/pci/mmconfig.c
arch/i386/pci/pci.h
arch/x86_64/pci/mmconfig.c

index b50595a0550f7d45d46358c2156e10154e9ed67c..7947cede871258939b3ecedfb1d16abce1fa86ef 100644 (file)
@@ -1183,6 +1183,8 @@ running once the system is up.
                                Mechanism 2.
                nommconf        [IA-32,X86_64] Disable use of MMCONFIG for PCI
                                Configuration
+               mmconf          [IA-32,X86_64] Force MMCONFIG. This is useful
+                               to override the builtin blacklist.
                nomsi           [MSI] If the PCI_MSI kernel config parameter is
                                enabled, this kernel boot option can be used to
                                disable the use of MSI interrupts system-wide.
index 0a362e3aeac55aba443e5901a71bbe7e465e841a..1220dd828ce3e929d4d069feda59bd16d94f50b3 100644 (file)
@@ -237,6 +237,11 @@ char * __devinit  pcibios_setup(char *str)
                pci_probe &= ~PCI_PROBE_MMCONF;
                return NULL;
        }
+       /* override DMI blacklist */
+       else if (!strcmp(str, "mmconf")) {
+               pci_probe |= PCI_PROBE_MMCONF_FORCE;
+               return NULL;
+       }
 #endif
        else if (!strcmp(str, "noacpi")) {
                acpi_noirq_set();
index 5effb2e663ed85befa5a3c6d381792dfea24f86e..ef5a2faa7d824728d4c44cade01a2f2c023adca2 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/acpi.h>
+#include <linux/dmi.h>
 #include <asm/e820.h>
 #include "pci.h"
 
@@ -187,9 +188,31 @@ static __init void unreachable_devices(void)
        }
 }
 
+static int disable_mcfg(struct dmi_system_id *d)
+{
+       printk("PCI: %s detected. Disabling MCFG.\n", d->ident);
+       pci_probe &= ~PCI_PROBE_MMCONF;
+       return 0;
+}
+
+static struct dmi_system_id __initdata dmi_bad_mcfg[] = {
+       /* Has broken MCFG table that makes the system hang when used */
+        {
+         .callback = disable_mcfg,
+         .ident = "Intel D3C5105 SDV",
+         .matches = {
+                     DMI_MATCH(DMI_BIOS_VENDOR, "Intel"),
+                     DMI_MATCH(DMI_BOARD_NAME, "D26928"),
+                     },
+         },
+         {}
+};
+
 void __init pci_mmcfg_init(void)
 {
-       if ((pci_probe & PCI_PROBE_MMCONF) == 0)
+       dmi_check_system(dmi_bad_mcfg);
+
+       if ((pci_probe & (PCI_PROBE_MMCONF_FORCE|PCI_PROBE_MMCONF)) == 0)
                return;
 
        acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
index bf4e79335388b533b6149dcf403533b6ce687c7e..49a849b3a2414712672ec97b57548df5fdf2b075 100644 (file)
@@ -16,7 +16,8 @@
 #define PCI_PROBE_CONF1                0x0002
 #define PCI_PROBE_CONF2                0x0004
 #define PCI_PROBE_MMCONF       0x0008
-#define PCI_PROBE_MASK         0x000f
+#define PCI_PROBE_MMCONF_FORCE 0x0010
+#define PCI_PROBE_MASK         0x00ff
 
 #define PCI_NO_SORT            0x0100
 #define PCI_BIOS_SORT          0x0200
index 8a4a0f9263ceda701f0284e8e35fa14ba768fbad..2d48a7941d489beff692a8abd50e1c444726e159 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/init.h>
 #include <linux/acpi.h>
 #include <linux/bitmap.h>
+#include <linux/dmi.h>
 #include <asm/e820.h>
 
 #include "pci.h"
@@ -164,11 +165,33 @@ static __init void unreachable_devices(void)
        }
 }
 
+static int disable_mcfg(struct dmi_system_id *d)
+{
+       printk("PCI: %s detected. Disabling MCFG.\n", d->ident);
+       pci_probe &= ~PCI_PROBE_MMCONF;
+       return 0;
+}
+
+static struct dmi_system_id __initdata dmi_bad_mcfg[] = {
+       /* Has broken MCFG table that makes the system hang when used */
+        {
+         .callback = disable_mcfg,
+         .ident = "Intel D3C5105 SDV",
+         .matches = {
+                     DMI_MATCH(DMI_BIOS_VENDOR, "Intel"),
+                     DMI_MATCH(DMI_BOARD_NAME, "D26928"),
+                     },
+         },
+         {}
+};
+
 void __init pci_mmcfg_init(void)
 {
        int i;
 
-       if ((pci_probe & PCI_PROBE_MMCONF) == 0)
+       dmi_check_system(dmi_bad_mcfg);
+
+       if ((pci_probe & (PCI_PROBE_MMCONF|PCI_PROBE_MMCONF_FORCE)) == 0)
                return;
 
        acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);