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. 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.

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?

(By the way, internationalization of error messages in syslog/dmesg/journald does not look like a good idea. It is very hard to understand if the message is given in French in this mailing list…)

Thanks very much for your help
Bertrand

Reply via email to