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