ae23c9
From 020cf375b572ccbda55ad45e34b7cb7ad2a469a2 Mon Sep 17 00:00:00 2001
ae23c9
From: Gerd Hoffmann <kraxel@redhat.com>
ae23c9
Date: Wed, 13 Jun 2018 14:07:30 +0200
ae23c9
Subject: [PATCH 151/268] usb-host: skip open on pending postload bh
ae23c9
ae23c9
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
ae23c9
Message-id: <20180613140730.16401-2-kraxel@redhat.com>
ae23c9
Patchwork-id: 80667
ae23c9
O-Subject: [RHEL-7.6 qemu-kvm-rhev PATCH 1/1] usb-host: skip open on pending postload bh
ae23c9
Bugzilla: 1572851
ae23c9
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
ae23c9
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
ae23c9
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
ae23c9
ae23c9
usb-host emulates a device unplug after live migration, because the
ae23c9
device state is unknown and unplug/replug makes sure the guest
ae23c9
re-initializes the device into a working state.  This can't be done in
ae23c9
post-load though, so post-load just schedules a bottom half which
ae23c9
executes after vmload is complete.
ae23c9
ae23c9
It can happen that the device autoscan timer hits the race window
ae23c9
between scheduling and running the bottom half, which in turn can
ae23c9
triggers an assert().
ae23c9
ae23c9
Fix that issue by just ignoring the usb_host_open() call in case the
ae23c9
bottom half didn't execute yet.
ae23c9
ae23c9
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1572851
ae23c9
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
ae23c9
Message-id: 20180503062932.17233-1-kraxel@redhat.com
ae23c9
(cherry picked from commit 3280ea8edede3814553aa19fa27a58daedd48ad9)
ae23c9
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
ae23c9
---
ae23c9
 hw/usb/host-libusb.c | 7 +++++++
ae23c9
 1 file changed, 7 insertions(+)
ae23c9
ae23c9
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
ae23c9
index 1b0be07..0290fb8 100644
ae23c9
--- a/hw/usb/host-libusb.c
ae23c9
+++ b/hw/usb/host-libusb.c
ae23c9
@@ -102,6 +102,7 @@ struct USBHostDevice {
ae23c9
     /* callbacks & friends */
ae23c9
     QEMUBH                           *bh_nodev;
ae23c9
     QEMUBH                           *bh_postld;
ae23c9
+    bool                             bh_postld_pending;
ae23c9
     Notifier                         exit;
ae23c9
 
ae23c9
     /* request queues */
ae23c9
@@ -866,6 +867,10 @@ static int usb_host_open(USBHostDevice *s, libusb_device *dev)
ae23c9
     int rc;
ae23c9
     Error *local_err = NULL;
ae23c9
 
ae23c9
+    if (s->bh_postld_pending) {
ae23c9
+        return -1;
ae23c9
+    }
ae23c9
+
ae23c9
     trace_usb_host_open_started(bus_num, addr);
ae23c9
 
ae23c9
     if (s->dh != NULL) {
ae23c9
@@ -1524,6 +1529,7 @@ static void usb_host_post_load_bh(void *opaque)
ae23c9
     if (udev->attached) {
ae23c9
         usb_device_detach(udev);
ae23c9
     }
ae23c9
+    dev->bh_postld_pending = false;
ae23c9
     usb_host_auto_check(NULL);
ae23c9
 }
ae23c9
 
ae23c9
@@ -1535,6 +1541,7 @@ static int usb_host_post_load(void *opaque, int version_id)
ae23c9
         dev->bh_postld = qemu_bh_new(usb_host_post_load_bh, dev);
ae23c9
     }
ae23c9
     qemu_bh_schedule(dev->bh_postld);
ae23c9
+    dev->bh_postld_pending = true;
ae23c9
     return 0;
ae23c9
 }
ae23c9
 
ae23c9
-- 
ae23c9
1.8.3.1
ae23c9