From 3c3302a82a69e181b967a8bef2678d6250b42321 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 21 Sep 2012 18:57:37 -0300 Subject: [RHEL6 qemu-kvm PATCH 16/23] ehci: Walk async schedule before and after migration RH-Author: Hans de Goede Message-id: <1348253864-3050-16-git-send-email-hdegoede@redhat.com> Patchwork-id: 42191 O-Subject: [RHEL-6.4 qemu-kvm PATCH 15/22] ehci: Walk async schedule before and after migration Bugzilla: 805172 RH-Acked-by: Uri Lublin RH-Acked-by: Arnon Gilboa RH-Acked-by: Gerd Hoffmann Signed-off-by: Hans de Goede Signed-off-by: Gerd Hoffmann Upstream commit: ceab6f96454fe6589d1b09ce64403c041d79f9d9 Conflicts: hw/usb-ehci.c --- hw/usb-ehci.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) Signed-off-by: Eduardo Habkost --- hw/usb-ehci.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c index 0546d43..a52814b 100644 --- a/hw/usb-ehci.c +++ b/hw/usb-ehci.c @@ -28,6 +28,7 @@ #include "pci.h" #include "monitor.h" #include "trace.h" +#include "sysemu.h" #define EHCI_DEBUG 0 @@ -2287,6 +2288,32 @@ static int usb_ehci_post_load(void *opaque, int version_id) return 0; } +static void usb_ehci_vm_state_change(void *opaque, int running, RunState state) +{ + EHCIState *ehci = opaque; + + /* + * We don't migrate the EHCIQueue-s, instead we rebuild them for the + * schedule in guest memory. We must do the rebuilt ASAP, so that + * USB-devices which have async handled packages have a packet in the + * ep queue to match the completion with. + */ + if (state == RUN_STATE_RUNNING) { + ehci_advance_async_state(ehci); + } + + /* + * The schedule rebuilt from guest memory could cause the migration dest + * to miss a QH unlink, and fail to cancel packets, since the unlinked QH + * will never have existed on the destination. Therefor we must flush the + * async schedule on savevm to catch any not yet noticed unlinks. + */ + if (state == RUN_STATE_SAVE_VM) { + ehci_advance_async_state(ehci); + ehci_queues_rip_unseen(ehci, 1); + } +} + static const VMStateDescription vmstate_ehci = { .name = "ehci", .version_id = 1, @@ -2418,6 +2445,7 @@ static int usb_ehci_initfn(PCIDevice *dev) QTAILQ_INIT(&s->pqueues); qemu_register_reset(ehci_reset, s); + qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, s); s->mem = cpu_register_io_memory(ehci_readfn, ehci_writefn, s); -- 1.7.11.4