[pve-devel] [PATCH qemu-server] Fix #2343 Add USB3 support for Spice USB redirection

Aaron Lauterer a.lauterer at proxmox.com
Wed Aug 28 16:26:35 CEST 2019


If USB3 is enabled for a USB port of host type spice add a USB3
controller and use it.

To not break live migration this is only enabled for qemu 4.1 and
higher.

Signed-off-by: Aaron Lauterer <a.lauterer at proxmox.com>
---
 PVE/QemuServer.pm     |  4 ++--
 PVE/QemuServer/USB.pm | 22 ++++++++++++++++------
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 6e3b19e..375a34b 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -3701,7 +3701,7 @@ sub config_to_command {
     }
 
     # add usb controllers
-    my @usbcontrollers = PVE::QemuServer::USB::get_usb_controllers($conf, $bridges, $arch, $machine_type, $usbdesc->{format}, $MAX_USB_DEVICES);
+    my @usbcontrollers = PVE::QemuServer::USB::get_usb_controllers($conf, $bridges, $arch, $machine_type, $kvmver, $usbdesc->{format}, $MAX_USB_DEVICES);
     push @$devices, @usbcontrollers if @usbcontrollers;
     my $vga = parse_vga($conf->{vga});
 
@@ -3808,7 +3808,7 @@ sub config_to_command {
     }
 
     # usb devices
-    my @usbdevices = PVE::QemuServer::USB::get_usb_devices($conf, $usbdesc->{format}, $MAX_USB_DEVICES);
+    my @usbdevices = PVE::QemuServer::USB::get_usb_devices($conf, $usbdesc->{format}, $MAX_USB_DEVICES, $machine_type, $kvmver);
     push @$devices, @usbdevices if @usbdevices;
     # serial devices
     for (my $i = 0; $i < $MAX_SERIAL_PORTS; $i++)  {
diff --git a/PVE/QemuServer/USB.pm b/PVE/QemuServer/USB.pm
index a2097b9..316eb09 100644
--- a/PVE/QemuServer/USB.pm
+++ b/PVE/QemuServer/USB.pm
@@ -3,6 +3,7 @@ package PVE::QemuServer::USB;
 use strict;
 use warnings;
 use PVE::QemuServer::PCI qw(print_pci_addr);
+use PVE::QemuServer;
 use PVE::JSONSchema;
 use base 'Exporter';
 
@@ -34,7 +35,7 @@ sub parse_usb_device {
 }
 
 sub get_usb_controllers {
-    my ($conf, $bridges, $arch, $machine, $format, $max_usb_devices) = @_;
+    my ($conf, $bridges, $arch, $machine, $kvmver, $format, $max_usb_devices) = @_;
 
     my $devices = [];
     my $pciaddr = "";
@@ -50,7 +51,10 @@ sub get_usb_controllers {
 	for (my $i = 0; $i < $max_usb_devices; $i++)  {
 	    next if !$conf->{"usb$i"};
 	    my $d = eval { PVE::JSONSchema::parse_property_string($format,$conf->{"usb$i"}) };
-	    next if !$d || $d->{usb3}; # do not add usb2 controller if we have only usb3 devices
+
+	    # don't add usb2 controller if usb3 device unless it's for spice and
+	    # qemu version < 4.1 - for live migration
+	    next if !$d || ($d->{usb3} && ($d->{host} ne "spice" || PVE::QemuServer::qemu_machine_feature_enabled($machine, $kvmver, 4, 1)));
 	    $use_usb2 = 1;
 	}
 	# include usb device config
@@ -63,7 +67,10 @@ sub get_usb_controllers {
     for (my $i = 0; $i < $max_usb_devices; $i++)  {
 	next if !$conf->{"usb$i"};
 	my $d = eval { PVE::JSONSchema::parse_property_string($format,$conf->{"usb$i"}) };
-	next if !$d || !$d->{usb3};
+
+	# don't add usb3 controller if usb3 device is for spice and qemu version
+	# < 4.1 - for live migrations
+	next if !$d || !$d->{usb3} || ($d->{host} eq 'spice' && !PVE::QemuServer::qemu_machine_feature_enabled($machine, $kvmver, 4, 1));
 	$use_usb3 = 1;
     }
 
@@ -74,7 +81,7 @@ sub get_usb_controllers {
 }
 
 sub get_usb_devices {
-    my ($conf, $format, $max_usb_devices) = @_;
+    my ($conf, $format, $max_usb_devices, $machine, $kvmver) = @_;
 
     my $devices = [];
 
@@ -87,9 +94,12 @@ sub get_usb_devices {
 	    my $hostdevice = parse_usb_device($d->{host});
 	    $hostdevice->{usb3} = $d->{usb3};
 	    if (defined($hostdevice->{spice}) && $hostdevice->{spice}) {
-		# usb redir support for spice, currently no usb3
+		# usb redir support for spice, usb3 available with qemu 4.1
+		my $bus = 'ehci';
+		$bus = 'xhci' if PVE::QemuServer::qemu_machine_feature_enabled($machine, $kvmver, 4, 1) && $hostdevice->{usb3};
+
 		push @$devices, '-chardev', "spicevmc,id=usbredirchardev$i,name=usbredir";
-		push @$devices, '-device', "usb-redir,chardev=usbredirchardev$i,id=usbredirdev$i,bus=ehci.0";
+		push @$devices, '-device', "usb-redir,chardev=usbredirchardev$i,id=usbredirdev$i,bus=$bus.0";
 	    } else {
 		push @$devices, '-device', print_usbdevice_full($conf, "usb$i", $hostdevice);
 	    }
-- 
2.20.1




More information about the pve-devel mailing list