TL;DR
Has anyone with an ASRock X470 Taichi (or any X470 board, for that matter) managed to successfully pass through an on-board USB controller to a guest VM without using the ACS kernel patch? If so, how did you go about doing it?
Due diligence
System:
- Ryzen 3700X
- X470 Taichi
- BIOS 3.77 (beta) with AGESA Combo-AM4 1.0.0.4 Patch B
- Linux kernel 5.3 (vanilla Ubuntu 19.10, no ACS or PCI 127 bug patches)
By following the steps in various guides (primarily the Pop!_OS How-To), and much trial and error, Iāve managed to cobble together a functioning Windows 10 VM with GPU pasthrough setup. Now that a beta BIOS is available for this board containing AGESA Combo-AM4 1.0.0.4 Patch B (which addresses IOMMU group separation and Unknown PCI header type ā127ā
issues), Iām attempting to get passthrough of a USB controller working as well.
Relevant IOMMU groups:
IOMMU Group 18:
02:00.0 USB controller [0c03]: Advanced Micro Devices, Inc. [AMD] Device [1022:43d0] (rev 01)
02:00.1 SATA controller [0106]: Advanced Micro Devices, Inc. [AMD] 400 Series Chipset SATA Controller [1022:43c8] (rev 01)
02:00.2 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD] 400 Series Chipset PCIe Bridge [1022:43c6] (rev 01)
03:00.0 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD] 400 Series Chipset PCIe Port [1022:43c7] (rev 01)
03:02.0 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD] 400 Series Chipset PCIe Port [1022:43c7] (rev 01)
03:03.0 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD] 400 Series Chipset PCIe Port [1022:43c7] (rev 01)
03:04.0 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD] 400 Series Chipset PCIe Port [1022:43c7] (rev 01)
03:09.0 PCI bridge [0604]: Advanced Micro Devices, Inc. [AMD] 400 Series Chipset PCIe Port [1022:43c7] (rev 01)
04:00.0 USB controller [0c03]: ASMedia Technology Inc. ASM2142 USB 3.1 Host Controller [1b21:2142]
05:00.0 SATA controller [0106]: ASMedia Technology Inc. ASM1062 Serial ATA Controller [1b21:0612] (rev 02)
06:00.0 PCI bridge [0604]: ASMedia Technology Inc. ASM1184e PCIe Switch Port [1b21:1184]
07:01.0 PCI bridge [0604]: ASMedia Technology Inc. ASM1184e PCIe Switch Port [1b21:1184]
07:03.0 PCI bridge [0604]: ASMedia Technology Inc. ASM1184e PCIe Switch Port [1b21:1184]
07:05.0 PCI bridge [0604]: ASMedia Technology Inc. ASM1184e PCIe Switch Port [1b21:1184]
07:07.0 PCI bridge [0604]: ASMedia Technology Inc. ASM1184e PCIe Switch Port [1b21:1184]
08:00.0 Network controller [0280]: Intel Corporation Dual Band Wireless-AC 3168NGW [Stone Peak] [8086:24fb] (rev 10)
0a:00.0 Ethernet controller [0200]: Intel Corporation I211 Gigabit Network Connection [8086:1539] (rev 03)
0b:00.0 USB controller [0c03]: Renesas Technology Corp. uPD720202 USB 3.0 Host Controller [1912:0015] (rev 02)
IOMMU Group 24:
11:00.3 USB controller [0c03]: Advanced Micro Devices, Inc. [AMD] Matisse USB 3.0 Host Controller [1022:149c]
Before attempting to mess around with passing through any of the on-board USB controllers, I tried using a dedicated Sedna 2 port card (with @FurryJackman tested uPD720202 controller). The card itself played well with the host system, but no matter which non-GPU slot I put it ināeither of the x1 slots or the bottom x8 slotāit would show up in group 18 along with nearly every other device attached to the chipset.
This left the USB controller sitting all by itself in group 24 the prime candidate for passthrough.
My first try was to simply add the PCI device to the VM in virt-manager and hope for the best. Shortly after attempting to boot the VM, the host system became unresponsive and required a hard reboot. Less than an ideal situation. At this point, I rolled up my sleeves and took a deep dive into kernel driver binding.
In its default state, the USB controller is bound to the xhci_hcd
driver.
$ sudo lspci -s 11:00.3 -nnkv
11:00.3 USB controller [0c03]: Advanced Micro Devices, Inc. [AMD] Matisse USB 3.0 Host Controller [1022:149c] (prog-if 30 [XHCI])
Subsystem: ASRock Incorporation Matisse USB 3.0 Host Controller [1849:7914]
Flags: bus master, fast devsel, latency 0, IRQ 67
Memory at f7800000 (64-bit, non-prefetchable) [size=1M]
Capabilities: [48] Vendor Specific Information: Len=08 <?>
Capabilities: [50] Power Management version 3
Capabilities: [64] Express Endpoint, MSI 00
Capabilities: [a0] MSI: Enable- Count=1/8 Maskable- 64bit+
Capabilities: [c0] MSI-X: Enable+ Count=8 Masked-
Capabilities: [100] Vendor Specific Information: ID=0001 Rev=1 Len=010 <?>
Capabilities: [150] Advanced Error Reporting
Capabilities: [2a0] Access Control Services
Capabilities: [370] Transaction Processing Hints
Kernel driver in use: xhci_hcd
My assumption is that it should be bound to vfio-pci
like the graphics card, so I added the device ID to the /etc/initramfs-tools/scripts/init-top/bind_vfio.sh
script used in the Pop!_OS guide. Turns out this method only works for dynamically loaded kernel modules; xhci_hcd
is built into the kernel.
$ grep xhci /lib/modules/$(uname -r)/modules.builtin
kernel/drivers/usb/host/xhci-hcd.ko
kernel/drivers/usb/host/xhci-pci.ko
Some manual manipulation later (before scripting a more elegant solution)ā¦
$ echo '0000:11:00.3' | sudo tee /sys/bus/pci/devices/0000\:11\:00.3/driver/unbind
$ echo '1022 149c' | sudo tee -a /sys/bus/pci/drivers/vfio-pci/new_id
ā¦and the controller was bound to vfio-pci
$ sudo lspci -s 11:00.3 -nnkv
11:00.3 USB controller [0c03]: Advanced Micro Devices, Inc. [AMD] Matisse USB 3.0 Host Controller [1022:149c] (prog-if 30 [XHCI])
Subsystem: ASRock Incorporation Matisse USB 3.0 Host Controller [1849:7914]
Flags: fast devsel, IRQ 67
Memory at f7800000 (64-bit, non-prefetchable) [size=1M]
Capabilities: [48] Vendor Specific Information: Len=08 <?>
Capabilities: [50] Power Management version 3
Capabilities: [64] Express Endpoint, MSI 00
Capabilities: [a0] MSI: Enable- Count=1/8 Maskable- 64bit+
Capabilities: [c0] MSI-X: Enable- Count=8 Masked-
Capabilities: [100] Vendor Specific Information: ID=0001 Rev=1 Len=010 <?>
Capabilities: [150] Advanced Error Reporting
Capabilities: [2a0] Access Control Services
Capabilities: [370] Transaction Processing Hints
Kernel driver in use: vfio-pci
Attempting to start the VM with the USB controller attached as a PCI device brought the system down again. syslog
shows a number of events around the time of the crash, most interesting seem to be these (right before a series of ^@
garbage characters)
kernel: [10358.050360] vfio-pci 0000:11:00.3: not ready 1023ms after FLR; waiting
kernel: [10360.094937] vfio-pci 0000:11:00.3: not ready 2047ms after FLR; waiting
kernel: [10363.166855] vfio-pci 0000:11:00.3: not ready 4095ms after FLR; waiting
kernel: [10368.286832] vfio-pci 0000:11:00.3: not ready 8191ms after FLR; waiting
kernel: [10377.503036] vfio-pci 0000:11:00.3: not ready 16383ms after FLR; waiting
libvirtd[2175]: Cannot start job (query, none, none) for domain win10; current job is (async nested, none, start) owned by (2187 remoteDispatchDomainCreate, 0 <null>, 2187 remoteDispatchDomainCreate (flags=0x0)) for (33s, 0s, 33s)
libvirtd[2175]: Timed out during operation: cannot acquire state change lock (held by monitor=remoteDispatchDomainCreate)
kernel: [10395.678823] vfio-pci 0000:11:00.3: not ready 32767ms after FLR; waiting
libvirtd[2175]: Cannot start job (query, none, none) for domain win10; current job is (async nested, none, start) owned by (2187 remoteDispatchDomainCreate, 0 <null>, 2187 remoteDispatchDomainCreate (flags=0x0)) for (63s, 0s, 63s)
libvirtd[2175]: Timed out during operation: cannot acquire state change lock (held by monitor=remoteDispatchDomainCreate)
The last thing Iāve tried is changing the āmanagedā attribute for the USB controllerās āhostdevā entry in the VMās domain XML to ānoā. I.e.
<hostdev mode='subsystem' type='pci' managed='no'>
<source>
<address domain='0x0000' bus='0x11' slot='0x00' function='0x3'/>
</source>
<address type='pci' domain='0x0000' bus='0x0a' slot='0x00' function='0x0'/>
</hostdev>
The documentation states that
For PCI devices, when managed is āyesā it is detached from the host before being passed on to the guest and reattached to the host after the guest exits.
The description for ānoā is a little more complicated and I donāt understand it completely. But I take it to mean that you are responsible for detaching/reattaching the device from the host system. Having manually bound the USB controller to vfio-pci
, I thought Iād already met this requirement. Powering on the VM yet again caused the host to crash.
Any insights into whatās happening here, or what I can do to get this working, are greatly appreciated.