diff options
author | Bjorn Helgaas <bjorn.helgaas@hp.com> | 2009-10-23 17:20:33 -0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-11-04 11:47:22 -0500 |
commit | 9a08f7d3506019e3833cd4394ca0d7da0ae3689f (patch) | |
tree | 7abb8e68a05ed05d25896b55689df1baf6ec897f | |
parent | 2992e545ea006992ec9dc91c4fa996ce1e15f921 (diff) |
x86/PCI: allow MMCONFIG above 4GB
The current whitelist requires a kernel change for every machine that has
MMCONFIG regions above 4GB, even if BIOS provides a correct MCFG table.
This patch expands the whitelist to include machines with a rev 1 or newer
MCFG table and a DMI_BIOS_DATE of 2010 or later. That way, we only need
kernel changes for new machines that provide incorrect MCFG tables.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
CC: Matthew Wilcox <willy@linux.intel.com>
CC: John Keller <jpk@sgi.com>
CC: Yinghai Lu <yhlu.kernel@gmail.com>
CC: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
CC: Andi Kleen <andi@firstfloor.org>
Acked-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
-rw-r--r-- | arch/x86/pci/mmconfig-shared.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 602c172d3bd5..02642773c29d 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/acpi.h> | 15 | #include <linux/acpi.h> |
16 | #include <linux/sfi_acpi.h> | 16 | #include <linux/sfi_acpi.h> |
17 | #include <linux/bitmap.h> | 17 | #include <linux/bitmap.h> |
18 | #include <linux/dmi.h> | ||
18 | #include <linux/sort.h> | 19 | #include <linux/sort.h> |
19 | #include <asm/e820.h> | 20 | #include <asm/e820.h> |
20 | #include <asm/pci_x86.h> | 21 | #include <asm/pci_x86.h> |
@@ -527,18 +528,31 @@ reject: | |||
527 | 528 | ||
528 | static int __initdata known_bridge; | 529 | static int __initdata known_bridge; |
529 | 530 | ||
530 | static int acpi_mcfg_64bit_base_addr __initdata = FALSE; | ||
531 | |||
532 | /* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ | 531 | /* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ |
533 | struct acpi_mcfg_allocation *pci_mmcfg_config; | 532 | struct acpi_mcfg_allocation *pci_mmcfg_config; |
534 | int pci_mmcfg_config_num; | 533 | int pci_mmcfg_config_num; |
535 | 534 | ||
536 | static int __init acpi_mcfg_oem_check(struct acpi_table_mcfg *mcfg) | 535 | static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg, |
536 | struct acpi_mcfg_allocation *cfg) | ||
537 | { | 537 | { |
538 | int year; | ||
539 | |||
540 | if (cfg->address < 0xFFFFFFFF) | ||
541 | return 0; | ||
542 | |||
538 | if (!strcmp(mcfg->header.oem_id, "SGI")) | 543 | if (!strcmp(mcfg->header.oem_id, "SGI")) |
539 | acpi_mcfg_64bit_base_addr = TRUE; | 544 | return 0; |
540 | 545 | ||
541 | return 0; | 546 | if (mcfg->header.revision >= 1) { |
547 | if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && | ||
548 | year >= 2010) | ||
549 | return 0; | ||
550 | } | ||
551 | |||
552 | printk(KERN_ERR PREFIX "MCFG region for %04x:%02x-%02x at %#llx " | ||
553 | "is above 4GB, ignored\n", cfg->pci_segment, | ||
554 | cfg->start_bus_number, cfg->end_bus_number, cfg->address); | ||
555 | return -EINVAL; | ||
542 | } | 556 | } |
543 | 557 | ||
544 | static int __init pci_parse_mcfg(struct acpi_table_header *header) | 558 | static int __init pci_parse_mcfg(struct acpi_table_header *header) |
@@ -574,13 +588,8 @@ static int __init pci_parse_mcfg(struct acpi_table_header *header) | |||
574 | 588 | ||
575 | memcpy(pci_mmcfg_config, &mcfg[1], config_size); | 589 | memcpy(pci_mmcfg_config, &mcfg[1], config_size); |
576 | 590 | ||
577 | acpi_mcfg_oem_check(mcfg); | ||
578 | |||
579 | for (i = 0; i < pci_mmcfg_config_num; ++i) { | 591 | for (i = 0; i < pci_mmcfg_config_num; ++i) { |
580 | if ((pci_mmcfg_config[i].address > 0xFFFFFFFF) && | 592 | if (acpi_mcfg_check_entry(mcfg, &pci_mmcfg_config[i])) { |
581 | !acpi_mcfg_64bit_base_addr) { | ||
582 | printk(KERN_ERR PREFIX | ||
583 | "MMCONFIG not in low 4GB of memory\n"); | ||
584 | kfree(pci_mmcfg_config); | 593 | kfree(pci_mmcfg_config); |
585 | pci_mmcfg_config_num = 0; | 594 | pci_mmcfg_config_num = 0; |
586 | return -ENODEV; | 595 | return -ENODEV; |