Pass an USB hub from a KVM host to a guest with libvirt

I have the following USB devices on a Linux server:

# lsusb -t
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ehci_hcd/2p, 480M
    |__ Port 1: Dev 2, If 0, Class=hub, Driver=hub/6p, 480M
        |__ Port 2: Dev 3, If 0, Class=HID, Driver=usbfs, 1.5M
        |__ Port 3: Dev 4, If 0, Class=hub, Driver=hub/4p, 480M
            |__ Port 1: Dev 8, If 0, Class=print, Driver=usbfs, 12M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci_hcd/2p, 480M
    |__ Port 1: Dev 2, If 0, Class=hub, Driver=hub/6p, 480M

I would like to pass the entire USB hub (Dev 4) to a Windows XP guest. In this a device attached and removed to the hub should be automatically handled by the guest (right?).

I tried the following code with virsh attach-device:

<hostdev mode='subsystem' type='usb' managed='yes'>
 <source>
  <address type='usb' bus='0x002' port='1.3' />
 </source>
</hostdev>

but it didn't work:

error: Failed to attach device from attach_hub.xml
error: internal error usb address needs device id

What am I doing wrong?


Solution 1:

xml for hub: https://libvirt.org/formatdomain.html#elementsHub

An example:

  <hub type='usb'>
     <address type='usb' bus='0' port='1'/>
  </hub>

https://www.redhat.com/archives/libvir-list/2011-August/msg00816.html

Solution 2:

I know this thread is a few years old, but I've been doing a few days worth of work on this exact topic and feel the question could use some of my answers.

First, per the Libvirt domain format documentation, the following snippet outlines the correct <hostdev> syntax:

...
<devices>
  <hostdev mode='subsystem' type='usb'>
    <source startupPolicy='optional'>
      <vendor id='0x1234'/>
      <product id='0xbeef'/>
    </source>
    <boot order='2'/>
  </hostdev>
</devices>
...

The reason for your error is due to the missing <vendor> and <product> tags for your USB <source>

Second, If you are running Ubuntu 16.04 or greater (like me), then you will have successful USB passthrough messages with the above XML device format when using the virsh attach-device hot-plug, but the device will never attach to the VM. This is the fault of AppArmor. I found a comment in another thread linking to this AppArmor Libvirt configuration to resolve USB passthrough issues, which I can confirm worked to resolve my issues.

The relevant AppArmor snippet:

In order for a software program to access the usb device correctly the apparmor abstraction for qemu must be changed. Edit /etc/apparmor.d/abstractions/libvirt-qemu add a line:

# this lets qemu read all USB device information and might be considered a security risk
/run/udev/data/* r,

Third, the "USB hubs" referenced in the other answers are not hubs in the scope of the host machine, but rather in the scope of the VM. From the same Libvirt doc:

The hub element has an optional sub-element with type='usb' which can tie the device to a particular controller[...]

Many devices have an optional sub-element to describe where the device is placed on the virtual bus presented to the guest.

Hope this helps somebody :)