USB Workaround for Windows VM

Hi folks,

While I wait for a possible solution for sharing Qubes usb devices (not just thumbdrives) with Windows HVM, I’m looking for other alternatives. (See: Windows support in Qubes for the development discussions.)

My needs: I have a webcam and thumbdrive that must be shared with the Windows HVM. I have a Yubikey (2FA USB device) that must be used to unlock the hard drive, login, and screen saver.

The solutions I’ve tried:

  • Option (A): QWT for Windows 10. Fails to install; it doesn’t copy required DLLs during the installation process. If I manually install the missing DLL files, then I can share a thumb drive from sys-usb to Windows VM, but not other types of USB devices. QWT’s documentation claims to support USB devices on Win10, but that hasn’t been true for years. (It appears to have broken in 2019, when Windows hardened their application sandbox.) See QWT at Contents/windows-tools.md at master · Qubes-Community/Contents · GitHub

  • Option (B): Xen tools. Qubes is based on Xen. If this were Xen without Qubes, then I could use the Xen Window Tools to share USB devices from dom0 to a Windows VM in domu. Except: their Win10 installer has the same “broken and hasn’t worked in years” problem. And while it works in Xen without Qubes, the Xen tools do not work under Qubes. See Xen Tools at Index of /pvdrivers/win

  • Option (C): dom0 patch. Dmitry has some dom0 patches for stubbing qrexec that permit sharing any USB device to a Windows VM. As I understand it (from looking at the github logs), his patches have been accepted into the master code base and are passing the nightly regression test builds. However, use ‘sudo qubes-dom0-update --enablerepo=qubes-dom0-current-testing’ does not seem to retrieve the patches. (Or it is retrieving them but it still isn’t working.) Note: If I can get this solution working, then this is definitely the best option.

  • Option (D): I could run vmware/virtualbox/qemu inside a Linux VM and have that run the Windows VM. Those virtual software packages do permit sharing USB devices. Running a VM in a VM is ugly, but doable. The issue here is that, for my needs, Win10 must be 64-bit. The VM-in-a-VM solution only supports 32-bit OSes. (Is there a way to do with with a 64-bit OS?)

I’m up to option (E). On my laptop, all external USB ports AND the built-in webcam are on one USB bus. (Keyboard and mouse are not on that bus.) I can tell sys-usb to ignore this USB bus and assign the bus directly to the Windows VM.

Good news: The Windows VM can directly access the webcam and thumb drive because it owns the USB’s PCI bus.

Bad news: The Qubes/Linux screensaver cannot see the Yubikey, because it’s a USB device.

My questions:

  1. Is there any way I can assign the bus to Windows but keep the Yubikey in sys-usb?
  2. Is there a working solution to any of the other options?
  3. Is there some other option that I could use to get around this problem? I’m even open to using some kind of virtual desktop from a local Linux VM to the local Windows VM.

re question 1 - generally no. But it does depend on the architecture. For example, on some hardware there is separation of USB3 and USB 2 ports into two hubs. In dom0, try lspci and see how many USB hubs you have. Then use a process of elimination to work out which hubs relate to which ports, by removing the pci passthrough for one hub, then plugging usb into each port and doing lsusb in sys-usb

its a bit longwinded, but its how i worked out how to split usb ports to different domU on the t430

you could do the same to leave some ports in sys-usb and others in your target domu with pci passthrough maybe?

Hi @Plexus,

I have tested with a couple of laptops. I have one laptop where the left side ports are on one bus, and the right side ports are on a different bus. But on this laptop (Dell 5550), all external USB ports are on the same bus. I can’t split one set of ports to sys-usb and another set to Windows.

Good idea, though! If I were working on a different laptop, then this could be an option.

Alternatively you could by a USB express card and have an extra USB
controller that way. That’s what I do to have USB in the Windows HVM.

Hi @Sven,

The standalone USB card for the PCI bus is a good option for a desktop computer. However, the laptop I’m using doesn’t have any PCI expansion slots.

Then use a process of elimination to work out which hubs relate to which ports, by removing the pci passthrough for one hub, then plugging usb into each port and doing lsusb in sys-usb

OK, how does one remove the pci passthrough for a hub? And can this be done if you have usb keyboard and mouse and are using sys-usb with the settings to account for that?

here’s what I’m trying to untangle:

I apparently have four usb controllers, but just on the basis of lsusb all plugs look to be on ONE controller (everything is on bus 4); but apparently that’s meaningless–especially since five distinct buses are listed by doing lsusb on a sys-usb terminal. The other four are just given names like “Linux Foundation 2.0 root hub”. I’m guessing that buses do not map to controllers, and your post indicates I have to do something more involved to figure out which controller controls which actual USB socket.

Here is lspci from dom0:

00:0d.0 USB controller: Intel Corporation Tiger Lake-LP Thunderbolt 4 USB Controller (rev 01)
00:0d.2 USB controller: Intel Corporation Tiger Lake-LP Thunderbolt 4 NHI #0 (rev 01)
00:0d.3 USB controller: Intel Corporation Tiger Lake-LP Thunderbolt 4 NHI #1 (rev 01)
00:14.0 USB controller: Intel Corporation Tiger Lake-LP USB 3.2 Gen 2x1 xHCI Host Controller (rev 20)

and here is lsusb on sys-usb:

00:0d.0 USB controller: Intel Corporation Tiger Lake-LP Thunderbolt 4 USB Controller (rev 01)
00:0d.2 USB controller: Intel Corporation Tiger Lake-LP Thunderbolt 4 NHI #0 (rev 01)
00:0d.3 USB controller: Intel Corporation Tiger Lake-LP Thunderbolt 4 NHI #1 (rev 01)
00:14.0 USB controller: Intel Corporation Tiger Lake-LP USB 3.2 Gen 2x1 xHCI Host Controller (rev 20)

Im afraid I havent had much experience with the tiger lake family, nor your specific motherboard configuration - however its the lspci output i was talking about in my post. You can look in qubes configuration for the sys-usb qubes and look for the PCI passthrough section to see what is in there. I am purely guessing here but your output looks (again: guesswork) like you have one USB2/3 (old style usb port handler) and two thunderbolt NHIs (which bridge USB-C ports to the PCI bus) - its (again: guesswork) possible that your old style USB slots have only one controller and the USB-Cs have more than one.

You are correct in that you are going to experience issues if you remove the device that controls your mouse and keyboard.

I think that if i were in your position and wanted to figure out which is which on a USB HID only Desktop, without running the risk of locking myself out of QubesOS, I would probably be booting debian off a USB stick and then using sysfs to disable the different PCI addresses

echo 1 > /sys/bus/pci/devices/0000:00:0d.0/remove

and see what breaks. Also I would have USB A to USB C adapters on hand to check various permutations using the USBC sockets too. I would then be able to use that information to go back into QubesOs and know what PCI addresses are which ports and use that accordingly in sys-usb and the windows qube(s)

1 Like

dom0:$ qvm-features VMNAME stubdom-qrexec 1

This works for my machine running 4.1…can pass webcam or usb-devices through to my windows 11 HVM and back.

I just realized I apparently posted lspci twice in my comment. I must have flubbed a ctrl-shift V or something.