Skip to content

Commit

Permalink
[PATCH] x86: Disable MMCONFIG on Intel SDV using DMI blacklist
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Andi Kleen authored and Linus Torvalds committed Aug 30, 2006
1 parent 8c74932 commit 40dd2d2
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 3 deletions.
2 changes: 2 additions & 0 deletions Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
5 changes: 5 additions & 0 deletions arch/i386/pci/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
25 changes: 24 additions & 1 deletion arch/i386/pci/mmconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion arch/i386/pci/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
25 changes: 24 additions & 1 deletion arch/x86_64/pci/mmconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 40dd2d2

Please sign in to comment.