On some chipsets, e.g., the AMD RS780, the MMCONFIG base address is set via a host bridge "BAR." But this isn't really a BAR in the sense of a decoder for addresses on a PCI bus. The host bridge converts host accesses to the MMCONFIG region into PCI configuration accesses, so the MMCONFIG addresses never appear on the PCI bus. In addition, this "BAR" is often larger than the MMCONFIG region proper, so it can overlap other real PCI devices, which causes resource allocation conflicts. PCI cannot move this BAR because the MMCONFIG code has already discovered it, so we might as well ignore it. Here's the typical signature, showing the spurious "no compatible bridge window" and "PNP resource overlaps PCI BAR" warnings: PCI: MMCONFIG for domain 0000 [bus 00-ff] at [mem 0xe0000000-0xefffffff] (base 0xe0000000) pci_root PNP0A03:00: host bridge window [mem 0x7ff00000-0xfebfffff] pci 0000:00:00.0: BAR 3: [mem 0xe0000000-0xffffffff 64bit] pci 0000:00:00.0: no compatible bridge window for [mem 0xe0000000-0xffffffff 64bit] pnp 00:02: disabling [mem 0x00000000-0x00000fff window] because it overlaps 0000:00:00.0 BAR 3 [mem 0x00000000-0x1fffffff 64bit] Note that when we didn't find a host bridge window for the BAR, we cleared the resource starting address (but not the BAR register itself), leading to the pnp 00:02 conflict. Reference: https://bugzilla.kernel.org/show_bug.cgi?id=19252 Signed-off-by: Bjorn Helgaas <bjorn.helgaas@xxxxxx> --- arch/x86/pci/fixup.c | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+), 0 deletions(-) diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index 08eba69..6656144 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c @@ -493,3 +493,32 @@ static void __devinit pci_siemens_interrupt_controller(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SIEMENS, 0x0015, pci_siemens_interrupt_controller); + +#ifdef CONFIG_PCI_MMCONFIG +/* + * Ignore any MMCONFIG BARs. These can't be reassigned because MMCONFIG code + * has already discovered them, and they often conflict with other devices. + */ +static void quirk_ignore_mmconfig_bar(struct pci_dev *dev) +{ + struct pci_mmcfg_region *cfg; + int i; + + list_for_each_entry(cfg, &pci_mmcfg_list, list) { + for (i = 0; i < 6; i++) { + struct resource *res = &dev->resource[i]; + + if (resource_type(res) == IORESOURCE_MEM && + res->start < cfg->res.end && + res->end > cfg->res.start) { + dev_info(&dev->dev, "BAR %d: %pR overlaps domain %04x [bus %02x-%02x] MMCONFIG region %pR; ignoring this BAR\n", + i, res, cfg->segment, cfg->start_bus, + cfg->end_bus, &cfg->res); + res->flags = 0; + res->start = 0; + } + } + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_ignore_mmconfig_bar); +#endif -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html