76daa3
From 6b86a8553b77e506de0529cb4e4aa0bd1db88322 Mon Sep 17 00:00:00 2001
76daa3
From: Gerd Hoffmann <kraxel@redhat.com>
76daa3
Date: Tue, 6 Jun 2017 15:43:53 +0200
76daa3
Subject: [PATCH 17/17] ehci: fix frame timer invocation.
76daa3
76daa3
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
76daa3
Message-id: <20170606154353.31670-3-kraxel@redhat.com>
76daa3
Patchwork-id: 75505
76daa3
O-Subject: [RHEL-7.4 qemu-kvm-rhev PATCH 2/2] ehci: fix frame timer invocation.
76daa3
Bugzilla: 1449609
76daa3
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
76daa3
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
76daa3
RH-Acked-by: Thomas Huth <thuth@redhat.com>
76daa3
76daa3
ehci registers ehci_frame_timer as both timer and bottom half, which
76daa3
turned out to be a bad idea as it can be called as bottom half then
76daa3
while it is running as timer, and it isn't prepared to handle recursive
76daa3
calls.
76daa3
76daa3
Change the timer func to just schedule the bottom half to avoid this.
76daa3
76daa3
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1449609
76daa3
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
76daa3
Message-id: 20170519120428.25981-1-kraxel@redhat.com
76daa3
(cherry picked from commit 3bfecee2cb71f21cd39d6183f18b446c01917573)
76daa3
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
76daa3
---
76daa3
 hw/usb/hcd-ehci.c | 13 ++++++++++---
76daa3
 1 file changed, 10 insertions(+), 3 deletions(-)
76daa3
76daa3
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
76daa3
index d7361e5..17c572c 100644
76daa3
--- a/hw/usb/hcd-ehci.c
76daa3
+++ b/hw/usb/hcd-ehci.c
76daa3
@@ -2232,7 +2232,7 @@ static void ehci_update_frindex(EHCIState *ehci, int uframes)
76daa3
     ehci->frindex = (ehci->frindex + uframes) % 0x4000;
76daa3
 }
76daa3
 
76daa3
-static void ehci_frame_timer(void *opaque)
76daa3
+static void ehci_work_bh(void *opaque)
76daa3
 {
76daa3
     EHCIState *ehci = opaque;
76daa3
     int need_timer = 0;
76daa3
@@ -2324,6 +2324,13 @@ static void ehci_frame_timer(void *opaque)
76daa3
     }
76daa3
 }
76daa3
 
76daa3
+static void ehci_work_timer(void *opaque)
76daa3
+{
76daa3
+    EHCIState *ehci = opaque;
76daa3
+
76daa3
+    qemu_bh_schedule(ehci->async_bh);
76daa3
+}
76daa3
+
76daa3
 static const MemoryRegionOps ehci_mmio_caps_ops = {
76daa3
     .read = ehci_caps_read,
76daa3
     .write = ehci_caps_write,
76daa3
@@ -2478,8 +2485,8 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp)
76daa3
         s->ports[i].dev = 0;
76daa3
     }
76daa3
 
76daa3
-    s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ehci_frame_timer, s);
76daa3
-    s->async_bh = qemu_bh_new(ehci_frame_timer, s);
76daa3
+    s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ehci_work_timer, s);
76daa3
+    s->async_bh = qemu_bh_new(ehci_work_bh, s);
76daa3
     s->device = dev;
76daa3
 
76daa3
     s->vmstate = qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, s);
76daa3
-- 
76daa3
1.8.3.1
76daa3