]> git.ipfire.org Git - thirdparty/libvirt.git/commit
Fix the ACS checking in the PCI code.
authorChris Lalancette <clalance@redhat.com>
Wed, 28 Jul 2010 20:53:00 +0000 (16:53 -0400)
committerChris Lalancette <clalance@redhat.com>
Mon, 2 Aug 2010 13:54:38 +0000 (09:54 -0400)
commit86b043ad3e1c6d15d8af6df68089d04fbec248e3
treec928af1e3b04eb28547fa496ad389702bf9e9ca4
parent32c6a959ac878f84b994aac37a39bf40ea1e22cf
Fix the ACS checking in the PCI code.

When trying to assign a PCI device to a guest, we have
to check that all bridges upstream of that device support
ACS.  That means that we have to find the parent bridge of
the current device, check for ACS, then find the parent bridge
of that device, check for ACS, etc.  As it currently stands,
the code to do this iterates through all PCI devices on the
system, looking for a device that has a range of busses that
included the current device's bus.

That check is not restrictive enough, though.  Depending on
how we iterated through the list of PCI devices, we could first
find the *topmost* bridge in the system; since it necessarily had
a range of busses including the current device's bus, we
would only ever check the topmost bridge, and not check
any of the intermediate bridges.

Note that this also caused a fairly serious bug in the
secondary bus reset code, where we could erroneously
find and reset the topmost bus instead of the inner bus.

This patch changes pciGetParentDevice() so that it first
checks if a bridge device's secondary bus exactly matches
the bus of the device we are looking for.  If it does, we've
found the correct parent bridge and we are done.  If it does not,
then we check to see if this bridge device's busses *include* the
bus of the device we care about.  If so, we mark this bridge device
as best, and go on.  If we later find another bridge device whose
busses include this device, but is more restrictive, then we
free up the previous best and mark the new one as best.  This
algorithm ensures that in the normal case we find the direct
parent, but in the case that the parent bridge secondary bus
is not exactly the same as the device, we still find the
correct bridge.

This patch was tested by me on a 4-port NIC with a
bridge without ACS (where assignment failed), a 4-port
NIC with a bridge with ACS (where assignment succeeded),
and a 2-port NIC with no bridges (where assignment
succeeded).

Signed-off-by: Chris Lalancette <clalance@redhat.com>
src/util/pci.c