USB Devices in Virtual Machines

From Proxmox VE
Jump to: navigation, search

Introduction

There can be good reasons to access to USB hardware directly from a guest as it would be part of the VM itself, e.g.:

  • Storage exclusively for the VM
  • Separate NIC for the VM, but Direct I/O not avaiable
  • Special device which needs a driver which exists only in the VM

The assignment of such devices can be predefined in the configuration file or "plugged" into the VM while it is running.

Simple Way: pass the USB device ID to the guest

Assigning an Alcor memory stick connected to the host to VM 804.

Figure out in the host the Device Type by

lsusb | grep Alcor

The result is

Bus 002 Device 013: ID 058f:6387 Alcor Micro Corp. Flash Drive

Assign it to the VM by

qm set 804 -usb0 host=058f:6387

Shutdown the VM (if running) and start it again.

Alternate way: pass the USB port to the guest

Example

In order to demonstrate how devices, physically connected to the host can be identified it´s assumed the following 7 USB devices are currently connected:

  1. External HD Toshiba USB 3.0
  2. memory stick Cruzer Blade USB 2.0
  3. memory stick SanDisk USB 2.0
  4. memory stick SanDisk USB 2.0 behind a USB hub
  5. memory stick Alcor behind the same USB hub as above
  6. Ethernet Network adapter USB 1.1 behind the same USB hub as above
  7. External HD Western Digital USB 3.0

Show Device Types

This is the simplest form and sufficient in most cases.

lsusb

The result is

Bus 002 Device 004: ID 0781:5567 SanDisk Corp. Cruzer Blade                                                     # <-------- (2)
Bus 002 Device 008: ID 0fe6:9700 Kontron (Industrial Computer Source / ICS Advent) DM9601 Fast Ethernet Adapter # <-------- (6)
Bus 002 Device 007: ID 0781:556b SanDisk Corp.                                                                  # <-------- (4)
Bus 002 Device 013: ID 058f:6387 Alcor Micro Corp. Flash Drive                                                  # <-------- (5)
Bus 002 Device 005: ID 05e3:0605 Genesys Logic, Inc. USB 2.0 Hub [ednet]
Bus 002 Device 010: ID 0781:556b SanDisk Corp.                                                                  # <-------- (3)
Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 003: ID 1058:0820 Western Digital Technologies, Inc.                                             # <-------- (7)
Bus 004 Device 002: ID 0480:a007 Toshiba America Info. Systems, Inc. External Disk USB 3.0                      # <-------- (1)
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

The numbers on the far right refer to the previously defined example. The other entries are the USB hubs of the system.

Note that the "Device" number is just a number assigned automatically by the host, independent where the device is connected to. If the device is removed and plugged in again it gets a new number.

Show Device Map and Types

Sometimes it is necessary to specify where a device is physically connected. This information can be obtained by

qm monitor 804

where "804" is the ID of a running VM - regardless which VM is specified, the following command inside of the monitor reports always the same

info usbhost

in case of our example it is

 Bus 2, Addr 4, Port 1.8, Speed 480 Mb/s
   Class 00: USB device 0781:5567, Cruzer Blade                       # <---- (2)
 Bus 2, Addr 8, Port 1.2.3, Speed 12 Mb/s
   Class 00: USB device 0fe6:9700, USB 2.0 10/100M Ethernet Adaptor   # <---- (6)
 Bus 2, Addr 7, Port 1.2.2, Speed 480 Mb/s
   Class 00: USB device 0781:556b, Cruzer Edge                        # <---- (4)
 Bus 2, Addr 13, Port 1.2.1, Speed 480 Mb/s
   Class 00: USB device 058f:6387, Mass Storage                       # <---- (5)
 Bus 2, Addr 10, Port 1.1, Speed 480 Mb/s
   Class 00: USB device 0781:556b, Cruzer Edge                        # <---- (3)
 Bus 4, Addr 3, Port 1, Speed 5000 Mb/s
   Class 00: USB device 1058:0820, My Passport 0820                   # <---- (7)
 Bus 4, Addr 2, Port 1, Speed 5000 Mb/s                                
   Class 00: USB device 0480:a007, External USB 3.0                   # <---- (1)


The devices behind the external hub have port addresses 1.2.x

This form shows also the currently used USB protocol (btw: even the device (6) calls itself "USB 2.0 10/100M Ethernet Adaptor" it works only as USB 1.1 device)

  • 12 MB/s = USB 1.1
  • 480 Mb/s = USB 2.0
  • 5000 Mb/s = USB 3.0

Just the map can be displayed by

lsusb -t

but it´s sometimes not complete and not recommended.

Complete Information

usb-devices

which contains everything but i´s a little bit difficult to read - for the current subject it´s sufficient to use the qm monitor as described above. The only one thing is a running VM must exist when processing the command.

Assigning Devices to VMs

Note that only "real" devices can be assigned, i.e. assigning of USB hubs is not possible.

In Configuration

General Remark

Using the below mentioned "qm set" command has the same effect as writing directly into the conf file. Moreover a preconfigured usb configuration file /usr/share/qemu-server/pve-usb.cfg could be adapted. But in order to avoid confusion this article recommends to use only the "qm set" command.

USB1.x, USB2.0

The syntax for assigning in configuration is (see also man page for qm)

qm set <VM-ID> -usb[<n>] host={ <bus>-<port>(.<port>)* | <vendor-id>:<product-id> }

According to the above example let´s say the Alcor stick and the Cruzer Edge connected to the external hub (which is device (4) from the example) should be assigned to VM 804:

For the Alcor stick (as already shown):

qm set 804 -usb0 host=058f:6387

For the Cruzer Edge this form will not be sufficient - there are two devices from the same type. Therefore the form specifying bus and port is used:

qm set 804 -usb1 host=2-1.2.2

More details about ports can be found here - but note as already mentioned the "lsusb -t" call is not reliable. Use "qm monitor" and "info usbhost" instead!

When the usb devices have to be removed from configuration the conf file has to be changed. In our example remove in /etc/pve/qemu-server/804.conf the following two lines:

usb0: host=058f:6387
usb1: host=host=2-1.2.2

USB3.0

since qemu-server package version 4.0-55 you also can set USB3 devices directly via the command line

qm set 804 -usb0 host=058f:6387,usb3=yes
qm set 804 -usb1 host=2-1.2.2,usb3=yes

it will automatically add the appropriate xhci controller at an available pci address

for any version <4.0-55 you can use the following instructions

1 Device

The external Toshiba drive should be assigned VM 804 and work with USB 3.0 protocol on a USB 3.0 port.

qm set 804 -args "-device nec-usb-xhci,id=xhci,addr=0x1b,bus=pci.1 -device usb-host,bus=xhci.0,vendorid=0x0480,productid=0xa007"

Note that "addr=0x5" works only if there is no other device assigned to this address. If a failure occurs because of double use of this address choose another one.

When the usb device has to be removed from configuration the conf file has to be changed. In our example remove in /etc/pve/qemu-server/804.conf the following line:

args: -device nec-usb-xhci,id=xhci,addr=0x1b,bus=pci.1 -device usb-host,bus=xhci.0,vendorid=0x0480,productid=0xa007
More Devices

For one machine only one "-args" argument is possible. If already an "-args" advice was given giving another one overwrites the first. Moreover, the usb3 driver needs only to be defined once. In the following example 2 USB3 devices are assigned to the VM, the second one has the ID 1058:0820

qm set 804 -args "-device nec-usb-xhci,id=xhci,addr=0x1b,bus=pci.1 -device usb-host,bus=xhci.0,vendorid=0x0480,productid=0xa007 \
-device usb-host,bus=xhci.0,vendorid=0x1058,productid=0x0820"

Assign Devices to an already Running VM

How to connect devices to a running machine without shutting it down is demonstrated by the examples from above. If device is assigned in that way the assignment is valid until the machine stops. The assignment is independent of the actual status of the device (whether it´s currently plugged in or not), i.e. it can be plugged in and out multiple times and will be always assigned to the VM; regardless if the "Productid" or "busaddress" method is used.

USB1.x, USB2.0

qm monitor 804
device_add usb-host,vendorid=0x058f,productid=0x6387,id=someid

device_add usb-host,hostbus=2,hostport=1.2.2,id=someotherid

Note that the "usb_add" command offered in "qm monitor" is NOT FUNCTIONING for this case!

someid and someotherid are ids of your choice, those can later be used to remove the usb device from the guest

USB3.0

qm monitor 804
device_add nec-usb-xhci,id=xhci,addr=0x1B,bus=pci.1
device_add usb-host,bus=xhci.0,vendorid=0x0480,productid=0xa007,id=anotherid

anotherid is chosen by you, so the device can later be removed again

Reassign to Host

To remove an USB device from a guest do the following:

  1. make sure the USB device is not in use in your guest operating system (e.g. with "Remove USB device" in Windows)
  2. connect to the qemu monitor for the vm either on the command line
    • qm monitor VMID
    • or on the web interface under VM->Monitor
  3. enter the following and replace <idofyourdevice> with the id of the usb device (e.g. usb0)
device_del <idofyourdevice>

now your USB device should be removed from your guest and reappear on the host, until you stop and start the VM again

to remove the USB device from the config of a VM, do

qm set VMID -delete 'usbX'

where usbX is the id of the USB device

caution: this does not remove the usb device from a running VM