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