USB passthrough test reports in 7.5RC1

  • @axiom00 yes, once I dug further I had the same issues. I don't have anything to pair with my stick yet, I was trying to get it working before splashing out on zigbee devices. I'm not sure why it's having issues. If you look at the Conbee serial protocol it's all done via binary commands sent over 38400 baud serial, so it should work OK. I also had an issue where my stick disconnected/reconnected after about an hour and came up with a different path in /dev so it didn't attach any more. I suspect this was because qemu was holding the original device open.

    To remove the device from the vm again do

    xe vm-param-remove vm-param-add uuid=<uuid> param-name=platform param-key=hvm_serial

    else it won't start if the serial device isn't present.

  • Further update: I've found the USB device is added to qemu after the vm has started through hot plugging. It seems this is done in xenopsd. It even has explicit code to support USB v1 devices in there

    According to xenopsd sources from 0.101.0 from the XCP-NG 8.0 SRPM, the code is

    let vusb_plug ~xs ~privileged ~domid ~id ~hostbus ~hostport ~version =
      debug "vusb_plug: plug VUSB device %s" id;
      let get_bus v =
        if String.startswith "1" v then
        else begin
          (* Here plug usb controller according to the usb version*)
          let usb_controller_driver = "usb-ehci" in
          let driver_id = "ehci" in
          vusb_controller_plug ~xs ~domid ~driver:usb_controller_driver ~driver_id;
          Printf.sprintf "%s.0" driver_id;
      if Qemu.is_running ~xs domid then
          (* Need to reset USB device before passthrough to vm according to CP-24616.
             Also need to do deprivileged work in usb_reset script if QEMU is deprivileged.
          begin match ~xs domid with
            | Some pid -> usb_reset_attach ~hostbus ~hostport ~domid ~pid ~privileged
            | _ -> raise (Xenopsd_error (Internal_error (Printf.sprintf "qemu pid does not exist for vm %d" domid)))
          let cmd = Qmp.(Device_add Device.(
                         { driver = "usb-host";
                           device = USB {
                    = id;
                             params = Some USB.({bus = get_bus version; hostbus; hostport})
          in qmp_send_cmd domid cmd |> ignore

    unfortunately I cannot find where the mysterious "version" parameter is that needs to be set to "1" to enable the use of USB bus 0 in the guest, which is USB 1. I'm wondering if it's stupidly reading the version string of the USB device itself rather than something else

    I note that the latest code in the upstream xapi-project/xenopsd line 1818 is radically different and now has a "speed" parameter. This was added in commit ab15e6c3b1b06b2eac4f2a8be724eac50c9d4b22 in Oct 2019 for CA-328130 (whatever that is). It looks like code was also added to the upstream xapi-project/xenapi to add the "speed" parameter to the data model there. So there may be a fix in a future version of XCP-NG if they pull in these fixes. I haven't looked at 8.1-beta but I suspect it's too late to go making wholesale changes there if the code hasn't already been merged.

    ok, just downloaded the SRPM from 8.1 xenopsd and it still has the old code for vusb plug, so I'm guessing 8.1 doesn't have this fixed (yet)

  • XCP-ng Team

    Can you create an issue asking for this detailed change to be made? We can create a test package with this change, so it won't impact other users 🙂

  • XCP-ng Team

    Thank you, perfect 🙂

  • OK, this is rather amusing. I've got USB passthrough working for my USB 1.0 device.

    [15:28 xcp-ng-bywirlgr log]# diff -u /opt/xensource/libexec/ /opt/xensource/libexec/
    --- /opt/xensource/libexec/     2019-11-04 10:03:02.000000000 +0000
    +++ /opt/xensource/libexec/  2020-03-01 15:20:53.323512746 +0000
    @@ -590,7 +590,8 @@
         pusb["path"] = device.get_node()
         # strip the leading space of "version"
    -    pusb["version"] = device[UsbDevice._VERSION].strip()
    +    #pusb["version"] = device[UsbDevice._VERSION].strip()
    +    pusb["version"] = "1.00"
         pusb["vendor-id"] = device[UsbDevice._ID_VENDOR]
         pusb["product-id"] = device[UsbDevice._ID_PRODUCT]
         pusb["vendor-desc"] = device[UsbDevice._DESC_VENDOR]

    I do NOT recommend this AT ALL. It is a gross hack. Apparently the xenopsd relies on the version number returned by the device to dictate the USB bus type of the controller it attaches to. I have no idea in what universe that makes sense.

    The above only works for me as that is the only USB device attached to the HV. I guess I could make the code a little smarter by looking for a particular device ID and only over-riding the version then

  • A slightly less hacky work around for USB v1 passthrough based on the issue I created:

    --- /opt/xensource/libexec/     2019-11-04 10:03:02.000000000 +0000
    +++ /tmp/    2020-03-01 17:32:29.266317478 +0000
    @@ -152,10 +152,11 @@
         _CLASS = "bDeviceClass"
         _CONF_VALUE = "bConfigurationValue"
         _NUM_INTERFACES = "bNumInterfaces"
    +    _USB_SPEED = "speed"
    -                        _CLASS, _CONF_VALUE, _NUM_INTERFACES]
    +                        _CLASS, _CONF_VALUE, _NUM_INTERFACES, _USB_SPEED]
    @@ -590,7 +591,10 @@
         pusb["path"] = device.get_node()
         # strip the leading space of "version"
    -    pusb["version"] = device[UsbDevice._VERSION].strip()
    +    if int(device[UsbDevice._USB_SPEED]) <= 12:
    +        pusb["version"] = "1.00"
    +    else:
    +        pusb["version"] = device[UsbDevice._VERSION].strip()
         pusb["vendor-id"] = device[UsbDevice._ID_VENDOR]
         pusb["product-id"] = device[UsbDevice._ID_PRODUCT]
         pusb["vendor-desc"] = device[UsbDevice._DESC_VENDOR]

    in theory any deice which is "low" or "full" speed (i.e. USB1) will have it's version number changed to 1.00 which forces xenopsd to use a USB1 bus. It may have side effects if the driver in the guest relies on the version number so caveat emptor.

  • Good Morning!
    I'm new to xcp-ng, we have two Hyper-V hosts but we needed to add a usb token to a vm, so we decided to migrate a host to xcp-ng for testing, but my host is not giving me the option passthrough usb, my server is a dell T110 II, I have already checked the bios settings and apparently everything is fine.
    I don't know what I could be doing wrong.
    I'm using version 8.1 of xcp-ng and xcp-ng center 20.04.
    I'm sorry if I posted the wrong call!


  • XCP-ng Team

    Hi. Does help in your situation?

  • @stormi
    Good Morning!
    When executing the command xe pusb-list I have no return.


  • @stormi Not at all sadly. The Device never passes though..

Log in to reply

XCP-ng Pro Support

XCP-ng Pro Support