Commit bf3e97df authored by Prarit Bhargava's avatar Prarit Bhargava Committed by Jiri Slaby

PCI: Disable all BAR sizing for devices with non-compliant BARs

commit ad67b437 upstream.

b84106b4 ("PCI: Disable IO/MEM decoding for devices with non-compliant
BARs") disabled BAR sizing for BARs 0-5 of devices that don't comply with
the PCI spec.  But it didn't do anything for expansion ROM BARs, so we
still try to size them, resulting in warnings like this on Broadwell-EP:

  pci 0000:ff:12.0: BAR 6: failed to assign [mem size 0x00000001 pref]

Move the non-compliant BAR check from __pci_read_base() up to
pci_read_bases() so it applies to the expansion ROM BAR as well as
to BARs 0-5.

Note that direct callers of __pci_read_base(), like sriov_init(), will now
bypass this check.  We haven't had reports of devices with broken SR-IOV
BARs yet.

[bhelgaas: changelog]
Fixes: b84106b4 ("PCI: Disable IO/MEM decoding for devices with non-compliant BARs")
Signed-off-by: default avatarPrarit Bhargava <prarit@redhat.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
CC: Thomas Gleixner <tglx@linutronix.de>
CC: Ingo Molnar <mingo@redhat.com>
CC: "H. Peter Anvin" <hpa@zytor.com>
CC: Andi Kleen <ak@linux.intel.com>
Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
parent 611a300c
...@@ -175,9 +175,6 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, ...@@ -175,9 +175,6 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
struct pci_bus_region region, inverted_region; struct pci_bus_region region, inverted_region;
bool bar_too_big = false, bar_disabled = false; bool bar_too_big = false, bar_disabled = false;
if (dev->non_compliant_bars)
return 0;
mask = type ? PCI_ROM_ADDRESS_MASK : ~0; mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
/* No printks while decoding is disabled! */ /* No printks while decoding is disabled! */
...@@ -319,6 +316,9 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) ...@@ -319,6 +316,9 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
{ {
unsigned int pos, reg; unsigned int pos, reg;
if (dev->non_compliant_bars)
return;
for (pos = 0; pos < howmany; pos++) { for (pos = 0; pos < howmany; pos++) {
struct resource *res = &dev->resource[pos]; struct resource *res = &dev->resource[pos];
reg = PCI_BASE_ADDRESS_0 + (pos << 2); reg = PCI_BASE_ADDRESS_0 + (pos << 2);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment