USB Passthrough on Ubuntu based VMs

Tutorial description

The default kernel used on an Ubuntu VM, linux-image-kvm, is a bare-bones kernel that is intended to be minimal in order to run Ubuntu inside a virtual machine.
This means that it will come with a minimum set of drivers, and any attempt to do a USB passthrough with that kernel will most probably fail as there are no active drivers for USB by default and you won’t be able to access the device inside of the VM.

This small tutorial explains how you can install a linux-image-virtual kernel inside an Ubuntu Focal based VM on LXD which will allow you to use a device after you configure the passthrough.
You should be able to run the same procedure on a VM from Focal onwards.


Host running the LXD VM
Find the Vendor ID and Product ID, these are the ID numbers found in lsusb, make sure to find and adjust accordingly to your Product ID and Number ID.

$ lsusb
Bus 001 Device 010: ID 058f:6387 Alcor Micro Corp. Flash Drive

As per the above, vendorid=058f and productid=6387.

Ensure that the VM is stopped.
lxc stop vm1

Add the device as per lsusb IDs, the flashdrive is the name of the device, it can be anything you want.
lxc config device add vm1 flashdrive usb vendorid=058f productid=6387

Start the VM, you should not be able to see anything with lsusb.

$ lxc exec vm1 bash
root@vm1:~# lsusb

Install the linux-image-virtual kernel inside the VM

Force the kernel to boot with Initrd.
root@vm1:~# rm /etc/default/grub.d/40-force-partuuid.cfg

Install the linux-image-virtual kernel.
root@vm1:~# sudo apt install linux-image-virtual

list the -kvm kernel

root@vm1:~# dpkg -l | grep "\-kvm"
ii  linux-headers-5.4.0-1046-kvm   5.4.0-1046.48                         amd64        Linux kernel headers for version 5.4.0 on 64 bit x86 SMP
ii  linux-headers-kvm                             amd64        Linux kernel headers for virtual systems.
ii  linux-image-5.4.0-1046-kvm     5.4.0-1046.48                         amd64        Signed kernel image kvm
ii  linux-image-kvm                               amd64        Linux kernel image for virtual systems.
ii  linux-kvm                                     amd64        Complete Linux kernel for virtual systems.
ii  linux-kvm-headers-5.4.0-1046   5.4.0-1046.48                         all          Header files related to Linux kernel version 5.4.0
ii  linux-modules-5.4.0-1046-kvm   5.4.0-1046.48                         amd64        Linux kernel extra modules for version 5.4.0 on 64 bit x86 SMP

Remove all related -kvm kernel images, modules and header files.
dpkg -l | grep "\-kvm" | awk {'print $2'} | DEBIAN_FRONTEND=noninteractive xargs apt purge -y

You should now reboot the VM to boot into the new kernel.

root@vm1:~# reboot
root@vm1:~# Error: websocket: close 1006 (abnormal closure): unexpected EOF

Wait a couple of seconds for the VM to boot, log into the VM and you should be now using the -generic kernel and able to see your devices.

$ lxc exec vm1 bash
root@vm1:~# uname -a
Linux vm1 5.4.0-84-generic #94-Ubuntu SMP Thu Aug 26 20:27:37 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux                                                                                                                                                                                         
root@vm1:~# lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 058f:6387 Alcor Micro Corp. Flash Drive
Bus 001 Device 002: ID 0409:55aa NEC Corp. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

As I added a flash drive, I can now see it with fdisk -l for example.

root@vm1:~# fdisk -l
Disk /dev/sda: 9.32 GiB, 10000007168 bytes, 19531264 sectors
Disk model: QEMU HARDDISK   
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 0FC6D41E-63DA-45DC-A0C5-EBB798E72BBA

Device      Start      End  Sectors  Size Type
/dev/sda1  227328 19531230 19303903  9.2G Linux filesystem
/dev/sda14   2048    10239     8192    4M BIOS boot
/dev/sda15  10240   227327   217088  106M EFI System

Partition table entries are not in disk order.

Disk /dev/sdb: 7.51 GiB, 8053063680 bytes, 15728640 sectors
Disk model: Flash Disk
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xe73fea8f

Device     Boot Start      End  Sectors  Size Id Type
/dev/sdb1        5120 15728639 15723520  7.5G  b W95 FAT32