Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9a08f7d3 authored by Bjorn Helgaas's avatar Bjorn Helgaas Committed by Jesse Barnes
Browse files

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: default avatarBjorn 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: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
parent 2992e545
Loading
Loading
Loading
Loading
+20 −11
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include <linux/acpi.h>
#include <linux/sfi_acpi.h>
#include <linux/bitmap.h>
#include <linux/dmi.h>
#include <linux/sort.h>
#include <asm/e820.h>
#include <asm/pci_x86.h>
@@ -527,20 +528,33 @@ static void __init pci_mmcfg_reject_broken(int early)

static int __initdata known_bridge;

static int acpi_mcfg_64bit_base_addr __initdata = FALSE;

/* The physical address of the MMCONFIG aperture.  Set from ACPI tables. */
struct acpi_mcfg_allocation *pci_mmcfg_config;
int pci_mmcfg_config_num;

static int __init acpi_mcfg_oem_check(struct acpi_table_mcfg *mcfg)
static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg,
					struct acpi_mcfg_allocation *cfg)
{
	int year;

	if (cfg->address < 0xFFFFFFFF)
		return 0;

	if (!strcmp(mcfg->header.oem_id, "SGI"))
		acpi_mcfg_64bit_base_addr = TRUE;
		return 0;

	if (mcfg->header.revision >= 1) {
		if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) &&
		    year >= 2010)
			return 0;
	}

	printk(KERN_ERR PREFIX "MCFG region for %04x:%02x-%02x at %#llx "
	       "is above 4GB, ignored\n", cfg->pci_segment,
	       cfg->start_bus_number, cfg->end_bus_number, cfg->address);
	return -EINVAL;
}

static int __init pci_parse_mcfg(struct acpi_table_header *header)
{
	struct acpi_table_mcfg *mcfg;
@@ -574,13 +588,8 @@ static int __init pci_parse_mcfg(struct acpi_table_header *header)

	memcpy(pci_mmcfg_config, &mcfg[1], config_size);

	acpi_mcfg_oem_check(mcfg);

	for (i = 0; i < pci_mmcfg_config_num; ++i) {
		if ((pci_mmcfg_config[i].address > 0xFFFFFFFF) &&
		    !acpi_mcfg_64bit_base_addr) {
			printk(KERN_ERR PREFIX
			       "MMCONFIG not in low 4GB of memory\n");
		if (acpi_mcfg_check_entry(mcfg, &pci_mmcfg_config[i])) {
			kfree(pci_mmcfg_config);
			pci_mmcfg_config_num = 0;
			return -ENODEV;