[PATCH] x86/PCI: ignore "BARs" that overlap MMCONFIG regions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux