diff options
-rw-r--r-- | arch/i386/pci/mmconfig.c | 11 | ||||
-rw-r--r-- | arch/x86_64/pci/mmconfig.c | 10 |
2 files changed, 21 insertions, 0 deletions
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 613789071f30..ee815c7d3e4c 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c @@ -12,8 +12,11 @@ #include <linux/pci.h> #include <linux/init.h> #include <linux/acpi.h> +#include <asm/e820.h> #include "pci.h" +#define MMCONFIG_APER_SIZE (256*1024*1024) + #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) /* The base address of the last MMCONFIG device accessed */ @@ -183,6 +186,14 @@ void __init pci_mmcfg_init(void) (pci_mmcfg_config[0].base_address == 0)) 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"); raw_pci_ops = &pci_mmcfg; pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index e616500207e4..dfe84c322552 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c @@ -9,6 +9,8 @@ #include <linux/init.h> #include <linux/acpi.h> #include <linux/bitmap.h> +#include <asm/e820.h> + #include "pci.h" #define MMCONFIG_APER_SIZE (256*1024*1024) @@ -161,6 +163,14 @@ void __init pci_mmcfg_init(void) (pci_mmcfg_config[0].base_address == 0)) 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 */ pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); if (pci_mmcfg_virt == NULL) { |