Possible issue with dangling PCI BARs

Benjamin Herrenschmidt
2007-12-13T03:00:37Z

While reworking the powerpc PCI resource management, to make it more
x86-like and use more of the generic code in setup-bus.c and
setup-res.c, I noticed something a bit fishy in the way we deal with
resources that we failed to assign.

That's especially problematic for us as we have to deal with all sort of
more or less crappy firmwares, so we need our PCI code to be as robust
as possible vs. whatever might have been there before the kernel kicks
in.

Now, let's say that we have a device for which a BAR contain a value out
of whack or conflicting with something else. We "see" that in
pcibios_allocate_resources() and set res->start to 0 (and offset
res->end accordingly).

At this stage, we thus have a resource that is marked as unassigned.
However, we haven't actually modified the BAR content. So the device is
still potentially decoding the conflicting addresses (which may have
been allocated to some other device).

Now, normally, pci_assign_unassigned_resources() will take care of that
and assign some new address to this device. However, that may fail
(bridge window too small for example). Which mean we leave a device with
a dangling BAR. In fact, a driver may even successfully call
pci_enable_device_bars() on it, provided that the device has several
resources and that the one that is/are requested by the driver (via the
bitmask argument) are not the one(s) that failed to allocate.

So not only we can have a dangling BAR, but nothing prevent us to
actually go turn IO or MEM decoding on in case it wasn't already the
case on that device.

Ben.