Skip to content

Commit

Permalink
usb-host: skip open on pending postload bh
Browse files Browse the repository at this point in the history
usb-host emulates a device unplug after live migration, because the
device state is unknown and unplug/replug makes sure the guest
re-initializes the device into a working state.  This can't be done in
post-load though, so post-load just schedules a bottom half which
executes after vmload is complete.

It can happen that the device autoscan timer hits the race window
between scheduling and running the bottom half, which in turn can
triggers an assert().

Fix that issue by just ignoring the usb_host_open() call in case the
bottom half didn't execute yet.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1572851
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20180503062932.17233-1-kraxel@redhat.com
  • Loading branch information
kraxel committed May 7, 2018
1 parent 2392ae6 commit 3280ea8
Showing 1 changed file with 7 additions and 0 deletions.
7 changes: 7 additions & 0 deletions hw/usb/host-libusb.c
Expand Up @@ -102,6 +102,7 @@ struct USBHostDevice {
/* callbacks & friends */
QEMUBH *bh_nodev;
QEMUBH *bh_postld;
bool bh_postld_pending;
Notifier exit;

/* request queues */
Expand Down Expand Up @@ -870,6 +871,10 @@ static int usb_host_open(USBHostDevice *s, libusb_device *dev)
int rc;
Error *local_err = NULL;

if (s->bh_postld_pending) {
return -1;
}

trace_usb_host_open_started(bus_num, addr);

if (s->dh != NULL) {
Expand Down Expand Up @@ -1528,6 +1533,7 @@ static void usb_host_post_load_bh(void *opaque)
if (udev->attached) {
usb_device_detach(udev);
}
dev->bh_postld_pending = false;
usb_host_auto_check(NULL);
}

Expand All @@ -1539,6 +1545,7 @@ static int usb_host_post_load(void *opaque, int version_id)
dev->bh_postld = qemu_bh_new(usb_host_post_load_bh, dev);
}
qemu_bh_schedule(dev->bh_postld);
dev->bh_postld_pending = true;
return 0;
}

Expand Down

0 comments on commit 3280ea8

Please sign in to comment.