提交 946f2ee5 编写于 作者: A Arjan van de Ven 提交者: Linus Torvalds

[PATCH] i386/x86-64: Check that MCFG points to an e820 reserved area

This patch introduces a user for the e820_all_mapped function:

There have been several machines that don't have a working MMCONFIG,
often because of a buggy MCFG table in the ACPI bios.  This patch adds a
simple sanity check that detects a whole bunch of these cases, and when
it detects it, linux now boots rather than crash-and-burns.

The accuracy of this detection can in principle be improved if there was
a "is this entire range in e820 with THIS attribute", but no such
function exist and the complexity needed for this is not really worth
it; this simple check already catches most cases anyway.
Signed-off-by: NArjan van de Ven <arjan@linux.intel.com>
Signed-off-by: NAndi Kleen <ak@suse.de>
Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
上级 95222368
...@@ -12,8 +12,11 @@ ...@@ -12,8 +12,11 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <asm/e820.h>
#include "pci.h" #include "pci.h"
#define MMCONFIG_APER_SIZE (256*1024*1024)
#define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG))
/* The base address of the last MMCONFIG device accessed */ /* The base address of the last MMCONFIG device accessed */
...@@ -183,6 +186,14 @@ void __init pci_mmcfg_init(void) ...@@ -183,6 +186,14 @@ void __init pci_mmcfg_init(void)
(pci_mmcfg_config[0].base_address == 0)) (pci_mmcfg_config[0].base_address == 0))
return; return;
if (!e820_all_mapped(pci_mmcfg_config[0].base_address,
pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE,
E820_RESERVED)) {
printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n");
printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
return;
}
printk(KERN_INFO "PCI: Using MMCONFIG\n"); printk(KERN_INFO "PCI: Using MMCONFIG\n");
raw_pci_ops = &pci_mmcfg; raw_pci_ops = &pci_mmcfg;
pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/bitmap.h> #include <linux/bitmap.h>
#include <asm/e820.h>
#include "pci.h" #include "pci.h"
#define MMCONFIG_APER_SIZE (256*1024*1024) #define MMCONFIG_APER_SIZE (256*1024*1024)
...@@ -161,6 +163,14 @@ void __init pci_mmcfg_init(void) ...@@ -161,6 +163,14 @@ void __init pci_mmcfg_init(void)
(pci_mmcfg_config[0].base_address == 0)) (pci_mmcfg_config[0].base_address == 0))
return; return;
if (!e820_all_mapped(pci_mmcfg_config[0].base_address,
pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE,
E820_RESERVED)) {
printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n");
printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
return;
}
/* RED-PEN i386 doesn't do _nocache right now */ /* RED-PEN i386 doesn't do _nocache right now */
pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL);
if (pci_mmcfg_virt == NULL) { if (pci_mmcfg_virt == NULL) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册