When working with KVM virtualization, passing through USB devices to guest VMs can be particularly useful for scenarios like:
- Testing USB hardware in isolated environments
- Running proprietary USB dongle-protected software
- Accessing specialized USB peripherals from within VMs
Before attempting USB passthrough, ensure your system meets these requirements:
# Verify KVM and libvirt are properly installed
$ virsh --version
$ lsmod | grep kvm
# Check USB controller support
$ lsusb -t
The first step is to properly identify your USB device on the host system:
$ lsusb
Bus 002 Device 004: ID 13fe:5100 Kingston Technology Company Inc. Flash Drive
Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Note the vendor ID (13fe) and product ID (5100) for your target device.
There are two primary methods to attach USB devices to KVM VMs:
Method 1: Permanent Attachment via XML
Edit your VM's configuration using virsh:
$ virsh edit your_vm_name
Add the following device section:
<devices>
<hostdev mode='subsystem' type='usb' managed='yes'>
<source>
<vendor id='0x13fe'/>
<product id='0x5100'/>
</source>
</hostdev>
</devices>
Method 2: Temporary Hotplug Attachment
For temporary attachment without VM restart:
$ virsh attach-device your_vm_name usb_device.xml
Where usb_device.xml contains the same hostdev configuration as above.
If your USB device isn't appearing in the guest VM:
Permission Problems
Check and adjust udev rules if needed:
# Create a udev rule for your device
SUBSYSTEM=="usb", ATTR{idVendor}=="13fe", ATTR{idProduct}=="5100", MODE="0666"
AppArmor/SELinux Restrictions
Temporarily disable to test:
$ sudo systemctl stop apparmor
$ sudo setenforce 0
USB Controller Conflicts
Ensure your VM has proper USB controller definitions:
<controller type='usb' index='0' model='ich9-ehci1'/>
<controller type='usb' index='0' model='ich9-uhci1'/>
Inside your guest VM, verify the device appears:
$ lsusb
$ dmesg | grep usb
For Windows VMs, you may need additional drivers:
- Install VirtIO drivers in the Windows VM
- Use the following device definition:
<hostdev mode='subsystem' type='usb' managed='yes'>
<source>
<vendor id='0x13fe'/>
<product id='0x5100'/>
</source>
<address type='usb' bus='0' port='1'/>
</hostdev>
For more flexible USB sharing:
$ sudo apt install spice-vdagent
$ virt-viewer --connect qemu:///system --spice-usbredir-auto-redirect-filter=0x03,-1,-1,-1,0
When working with KVM virtualization, passing through USB devices can be particularly challenging due to the complex interaction between host systems, virtual machines, and USB controllers. The key challenge lies in ensuring proper device isolation and driver handling between host and guest systems.
Before attempting USB passthrough, it's crucial to examine your VM configuration. The XML dump reveals several important aspects of your current setup:
<controller type='usb' index='0' model='ich9-ehci1'>
<alias name='usb0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x7'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci1'>
<alias name='usb0'/>
<master startport='0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0' multifunction='on'/>
</controller>
The error message indicating the USB device is in use by QEMU while remaining accessible on the host suggests a conflict in device ownership. This typically occurs when:
- The host system maintains control over the USB device
- Permissions prevent proper device handoff
- The VM lacks proper USB controller support
Here's a more robust approach to USB passthrough:
# First, identify the USB device
lsusb -v
# Then detach it from the host kernel driver
sudo sh -c "echo 0 > /sys/bus/usb/devices/2-4/bConfigurationValue"
sudo sh -c "echo -n '2-4' > /sys/bus/usb/drivers/usb/unbind"
# Modify your VM configuration with virsh edit
<hostdev mode='subsystem' type='usb' managed='no'>
<source>
<vendor id='0x13fe'/>
<product id='0x5100'/>
<address bus='2' device='4'/>
</source>
<address type='usb' bus='0' port='1'/>
</hostdev>
If the basic approach fails, consider these advanced methods:
# Check kernel messages for USB events
dmesg | grep -i usb
# Verify QEMU permissions
ls -l /dev/bus/usb/*/*
# Temporarily disable USB autosuspend
for i in /sys/bus/usb/devices/*/power/autosuspend; do
echo -1 > $i
done
When direct passthrough fails, consider these alternatives:
- Use USB redirection via SPICE protocol
- Create a dedicated USB controller for the VM
- Implement USB/IP for network-based sharing
# Example of dedicated USB controller
<controller type='usb' index='1' model='nec-xhci'>
<alias name='usb1'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
</controller>