Blame SOURCES/kvm-Introduce-new-no_guest_reset-parameter-for-usb-host-.patch

7711c0
From 8db99b422a6de4d19a93429a221e26afa03f32ef Mon Sep 17 00:00:00 2001
7711c0
From: Gerd Hoffmann <kraxel@redhat.com>
7711c0
Date: Mon, 3 Jun 2019 13:45:47 +0200
7711c0
Subject: [PATCH 4/9] Introduce new "no_guest_reset" parameter for usb-host
7711c0
 device
7711c0
7711c0
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
7711c0
Message-id: <20190603134550.30153-2-kraxel@redhat.com>
7711c0
Patchwork-id: 88446
7711c0
O-Subject: [RHEL-7.7 qemu-kvm-rhev PATCH 1/4] Introduce new "no_guest_reset" parameter for usb-host device
7711c0
Bugzilla: 1710861
7711c0
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
7711c0
RH-Acked-by: Max Reitz <mreitz@redhat.com>
7711c0
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
7711c0
7711c0
From: Alexander Kappner <agk@godking.net>
7711c0
7711c0
With certain USB devices passed through via usb-host, a guest attempting to
7711c0
reset a usb-host device can trigger a reset loop that renders the USB device
7711c0
unusable. In my use case, the device was an iPhone XR that was passed through to
7711c0
a Mac OS X Mojave guest. Upon connecting the device, the following happens:
7711c0
7711c0
1) Guest recognizes new device, sends reset to emulated USB host
7711c0
2) QEMU's USB host sends reset to host kernel
7711c0
3) Host kernel resets device
7711c0
4) After reset, host kernel determines that some part of the device descriptor
7711c0
has changed ("device firmware changed" in dmesg), so host kernel decides to
7711c0
re-enumerate the device.
7711c0
5) Re-enumeration causes QEMU to disconnect and reconnect the device in the
7711c0
guest.
7711c0
6) goto 1)
7711c0
7711c0
Here's from the host kernel (note the "device firmware changed" lines")
7711c0
7711c0
[3677704.473050] usb 1-1.3: new high-speed USB device number 53 using ehci-pci
7711c0
[3677704.555594] usb 1-1.3: New USB device found, idVendor=05ac, idProduct=12a8, bcdDevice=11.08
7711c0
[3677704.555599] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
7711c0
[3677704.555602] usb 1-1.3: Product: iPhone
7711c0
[3677704.555605] usb 1-1.3: Manufacturer: Apple Inc.
7711c0
[3677704.555607] usb 1-1.3: SerialNumber: [[removed]]
7711c0
[3677709.401040] usb 1-1.3: reset high-speed USB device number 53 using ehci-pci
7711c0
[3677709.479486] usb 1-1.3: device firmware changed
7711c0
[3677709.479842] usb 1-1.3: USB disconnect, device number 53
7711c0
[3677709.546039] usb 1-1.3: new high-speed USB device number 54 using ehci-pci
7711c0
[3677709.627471] usb 1-1.3: New USB device found, idVendor=05ac, idProduct=12a8, bcdDevice=11.08
7711c0
[3677709.627476] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
7711c0
[3677709.627479] usb 1-1.3: Product: iPhone
7711c0
[3677709.627481] usb 1-1.3: Manufacturer: Apple Inc.
7711c0
[3677709.627483] usb 1-1.3: SerialNumber: [[removed]]
7711c0
[3677762.320044] usb 1-1.3: reset high-speed USB device number 54 using ehci-pci
7711c0
[3677762.615630] usb 1-1.3: USB disconnect, device number 54
7711c0
[3677762.787043] usb 1-1.3: new high-speed USB device number 55 using ehci-pci
7711c0
[3677762.869016] usb 1-1.3: New USB device found, idVendor=05ac, idProduct=12a8, bcdDevice=11.08
7711c0
[3677762.869024] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
7711c0
[3677762.869028] usb 1-1.3: Product: iPhone
7711c0
[3677762.869032] usb 1-1.3: Manufacturer: Apple Inc.
7711c0
[3677762.869035] usb 1-1.3: SerialNumber: [[removed]]
7711c0
[3677815.662036] usb 1-1.3: reset high-speed USB device number 55 using ehci-pci
7711c0
7711c0
Here's from QEMU:
7711c0
7711c0
libusb: error [_get_usbfs_fd] libusb couldn't open USB device /dev/bus/usb/005/022: No such file or directory
7711c0
libusb: error [udev_hotplug_event] ignoring udev action bind
7711c0
libusb: error [udev_hotplug_event] ignoring udev action bind
7711c0
libusb: error [_open_sysfs_attr] open /sys/bus/usb/devices/5-1/bConfigurationValue failed ret=-1 errno=2
7711c0
libusb: error [_get_usbfs_fd] File doesn't exist, wait 10 ms and try again
7711c0
7711c0
libusb: error [_get_usbfs_fd] libusb couldn't open USB device /dev/bus/usb/005/024: No such file or directory
7711c0
libusb: error [udev_hotplug_event] ignoring udev action bind
7711c0
libusb: error [udev_hotplug_event] ignoring udev action bind
7711c0
libusb: error [_open_sysfs_attr] open /sys/bus/usb/devices/5-1/bConfigurationValue failed ret=-1 errno=2
7711c0
libusb: error [_get_usbfs_fd] File doesn't exist, wait 10 ms and try again
7711c0
7711c0
libusb: error [_get_usbfs_fd] libusb couldn't open USB device /dev/bus/usb/005/026: No such file or directory
7711c0
7711c0
The result of this is that the device remains permanently unusable in the guest.
7711c0
The same problem has been previously reported for an iPad:
7711c0
https://stackoverflow.com/questions/52617634/how-do-i-get-qemu-usb-passthrough-to-work-for-ipad-iphone
7711c0
7711c0
This problem can be elegantly solved by interrupting step 2) above. Instead of
7711c0
passing through the reset, QEMU simply ignores it. To allow this to be
7711c0
configured on a per-device level,  a new parameter "no_guest_reset" is
7711c0
introduced for the usb-host device. I can confirm that the configuration
7711c0
described above (iPhone XS + Mojave guest) works flawlessly with
7711c0
no_guest_reset=True specified.
7711c0
7711c0
Working command line for my scenario:
7711c0
device_add usb-host,vendorid=0x05ac,productid=0x12a8,no_guest_reset=True,id=iphone
7711c0
7711c0
Best regards
7711c0
Alexander
7711c0
7711c0
Signed-off-by: Alexander Kappner <agk@godking.net>
7711c0
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
7711c0
Message-id: 20190128140027.9448-1-kraxel@redhat.com
7711c0
7711c0
[ kraxel: rename parameter to "guest-reset" ]
7711c0
7711c0
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
7711c0
(cherry picked from commit ba4c735b4fc74e309ce4b2551d258e442ef513a5)
7711c0
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
7711c0
---
7711c0
 hw/usb/host-libusb.c | 7 ++++++-
7711c0
 1 file changed, 6 insertions(+), 1 deletion(-)
7711c0
7711c0
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
7711c0
index 0290fb8..0425f0e 100644
7711c0
--- a/hw/usb/host-libusb.c
7711c0
+++ b/hw/usb/host-libusb.c
7711c0
@@ -82,7 +82,7 @@ struct USBHostDevice {
7711c0
     uint32_t                         options;
7711c0
     uint32_t                         loglevel;
7711c0
     bool                             needs_autoscan;
7711c0
-
7711c0
+    bool                             allow_guest_reset;
7711c0
     /* state */
7711c0
     QTAILQ_ENTRY(USBHostDevice)      next;
7711c0
     int                              seen, errcount;
7711c0
@@ -1447,6 +1447,10 @@ static void usb_host_handle_reset(USBDevice *udev)
7711c0
     USBHostDevice *s = USB_HOST_DEVICE(udev);
7711c0
     int rc;
7711c0
 
7711c0
+    if (!s->allow_guest_reset) {
7711c0
+        return;
7711c0
+    }
7711c0
+
7711c0
     trace_usb_host_reset(s->bus_num, s->addr);
7711c0
 
7711c0
     rc = libusb_reset_device(s->dh);
7711c0
@@ -1564,6 +1568,7 @@ static Property usb_host_dev_properties[] = {
7711c0
     DEFINE_PROP_UINT32("productid", USBHostDevice, match.product_id, 0),
7711c0
     DEFINE_PROP_UINT32("isobufs",  USBHostDevice, iso_urb_count,    4),
7711c0
     DEFINE_PROP_UINT32("isobsize", USBHostDevice, iso_urb_frames,   32),
7711c0
+    DEFINE_PROP_BOOL("guest-reset", USBHostDevice, allow_guest_reset, true),
7711c0
     DEFINE_PROP_UINT32("loglevel",  USBHostDevice, loglevel,
7711c0
                        LIBUSB_LOG_LEVEL_WARNING),
7711c0
     DEFINE_PROP_BIT("pipeline",    USBHostDevice, options,
7711c0
-- 
7711c0
1.8.3.1
7711c0