On Wed, Feb 04, 2026 at 09:02:47AM +0000, Daniel P. Berrangé via Devel wrote: > On Tue, Feb 03, 2026 at 11:12:18PM +0100, Bertrand Leconte wrote: > > Hello, > > > > I am using libvirt within Qubes OS (https://www.qubes-or.org). > > > > My laptop is a Lenovo P16 Gen 3 with an Intel Core Ultra 9 275HX, which is > > in the Arrow Lake family. The associated PCH is an Intel 800 Series WM880. > > The particularity of this platform is that the PCH includes a dedicated PCI > > Root Complex in addition to the CPU one.
The closest I have is a Lunar Lake device (226V), but this one has only a single root complex, so I can't verify this directly. Bertrand, can you share `lspci -t` output, and also `lspci -vvs 80:00.0` ? > > That means that I have devices connected to `0000:00` bus (addresses like > > 0000:00:xx.x) and devices connected to `0000:80` bus (addresses like > > 0000:80:xx.x). > > The consequence of that architecture is that there is no PCI Root Port > > serving the `0000:80` bus. > > > > When I want to PCI passthrough my USB controller device `0000:80:14.0`, the > > function `virPCIDeviceIsBehindSwitchLackingACS()` says that `Failed to find > > parent device for 0000:80:14.0`. > > > > When I look into the source code, it looks like it enumerates all PCI > > devices, searching for the Root Port managing the bus `0000:80`. As I said > > before, it cannot find any as it's A Root Complex that manage the `0000:80` > > bus and not a Root Port (a Root Complex it's not a PCI/PCIe device). > > However, for any device connected to PCI bus `0000:00`, it cannot find any > > PCI Root Port either but there is an exception in the code for it. > > > > @Bloged (one of Qubes OS users) proposed in > > https://forum.qubes-os.org/t/aistone-x6ar57ty-aka-tongfang-x6-16-intel-high-end-performance/37944/2 > > to change the code to > > diff --git a/src/util/virpci.c b/src/util/virpci.c > > index 3816369..fbed8f5 100644 > > --- a/src/util/virpci.c > > +++ b/src/util/virpci.c > > @@ -2555,12 +2555,20 @@ virPCIDeviceIsBehindSwitchLackingACS(virPCIDevice > > *dev) > > if (virPCIDeviceGetParent(dev, &parent) < 0) > > return -1; > > if (!parent) { > > - /* if we have no parent, and this is the root bus, ACS doesn't come > > - * into play since devices on the root bus can't P2P without going > > - * through the root IOMMU. > > + /* if we have no parent, and this is a root-like bus (0 > > or 0x80), > > + * ACS doesn't come into play since devices on these buses can't > > P2P > > + * without going through the root IOMMU. > > + * > > + * Arrow Lake (Intel Core Ultra 200 series) uses bus 0x80 for > > integrated > > + * devices like USB controllers, with a complex PCH topology that > > confuses > > + * parent device detection. Treat bus 0x80 like bus 0 for ACS > > purposes. > > */ > > if (dev->address.bus == 0) { > > return 0; > > + } else if (dev->address.bus == 0x80) { > > + VIR_DEBUG("%s %s: Arrow Lake bus 0x80 device, treating as root > > bus for ACS check", > > + dev->id, dev->name); > > + return 0; > > } else { > > virReportError(VIR_ERR_INTERNAL_ERROR, > > _("Failed to find parent device for %1$s"), > > -- > > > > > > This patch works, but it does not look very generic. > > Indeed, the correct way would be to look at /sys/devices/pciNNNN.NN to > identity root complexes, but..... Interestingly, I do have a device with a root complex at 0x80, and also at 0xc0, and libvirt is happy about assigning devices behind them (specifically, c1:00.0, which is behind root complex at 0xc0). I guess virPCIDeviceGetParent() does find the parent in my case. That particular HW runs older libvirt version (still 8.9.0...), and I can't check right now how it behaves on the newer version. But looking at the diff since then, I don't see any relevant changes. Relevant part of `lspci -t`: +-[0000:80]-+-00.0 | +-00.2 | +-01.0 | +-02.0 | +-03.0 | +-03.1-[81]-- | +-03.2-[82]-- ... \-[0000:c0]-+-00.0 +-00.2 +-01.0 +-02.0 +-03.0 +-03.1-[c1]----00.0 +-03.2-[c2]----00.0 +-03.3-[c3]----00.0 +-03.4-[c4]----00.0 > > In addition to that, a thread in 2017 (this mailing list) seems to indicate > > that this part of the code may not be necessary: > > https://lists.libvirt.org/archives/list/[email protected]/thread/QRI4L5YFGBAV7NCTJ5OOJ7GBYGHQ7WZQ/#K5WRR6WTAUEPRQBWJVJSMX554DTYFTYH. > > > > My question: can someone that knows this part of the code have a look to see > > what is the best way to correct it: either propose a patch to > > `virPCIDeviceIsBehindSwitchLackingACS` that is more generic or to change the > > rest of the code so it's no more used? > > ....That thread certainly suggests we have a large set of code that can > be purged. Libvirt only needs to support the 2 most recent releases of > each distro, and since the kerenl removed legacy device assignment 8 > years ago I see no reason for us to keep this. IIUC that thread is talking about KVM only. Here we have Xen. I'm not sure what "legacy assignment" is in the KVM world, but I don't think there were any changes in this API on Xen side in the last decade or so. Theoretically, checks like this should be done by Xen (either libxl, or the hypervisor itself). But in practice, libvirt does it more comprehensively and provides better error messages (when it works). -- Best Regards, Marek Marczykowski-Górecki Invisible Things Lab
signature.asc
Description: PGP signature
