Blame 0136-ehci-trace-guest-bugs.patch

5544c1
From 82b29b635d26ad0f5e14fabdf0956e9b8e7dbbfb Mon Sep 17 00:00:00 2001
Hans de Goede c8dfc6
From: Gerd Hoffmann <kraxel@redhat.com>
Hans de Goede c8dfc6
Date: Fri, 31 Aug 2012 10:44:21 +0200
5544c1
Subject: [PATCH] ehci: trace guest bugs
Hans de Goede c8dfc6
Hans de Goede c8dfc6
make qemu_queue_{cancel,reset} return the number of packets released,
Hans de Goede c8dfc6
so the caller can figure whenever there have been active packets even
Hans de Goede c8dfc6
though there shouldn't have been any.  Add tracepoint to log this.
Hans de Goede c8dfc6
Hans de Goede c8dfc6
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
5544c1
(cherry picked from commit 5c514681abbb3ae2f61f517c1aa3197f2f3ca93c)
5544c1
5544c1
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Hans de Goede c8dfc6
---
Hans de Goede c8dfc6
 hw/usb/hcd-ehci.c | 26 ++++++++++++++++++++------
Hans de Goede c8dfc6
 trace-events      |  1 +
Hans de Goede c8dfc6
 2 files changed, 21 insertions(+), 6 deletions(-)
Hans de Goede c8dfc6
Hans de Goede c8dfc6
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
Hans de Goede c8dfc6
index 23221d0..4564615 100644
Hans de Goede c8dfc6
--- a/hw/usb/hcd-ehci.c
Hans de Goede c8dfc6
+++ b/hw/usb/hcd-ehci.c
Hans de Goede c8dfc6
@@ -716,6 +716,12 @@ static void ehci_trace_sitd(EHCIState *s, target_phys_addr_t addr,
Hans de Goede c8dfc6
                         (bool)(sitd->results & SITD_RESULTS_ACTIVE));
Hans de Goede c8dfc6
 }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
+static void ehci_trace_guest_bug(EHCIState *s, const char *message)
Hans de Goede c8dfc6
+{
Hans de Goede c8dfc6
+    trace_usb_ehci_guest_bug(message);
Hans de Goede c8dfc6
+    fprintf(stderr, "ehci warning: %s\n", message);
Hans de Goede c8dfc6
+}
Hans de Goede c8dfc6
+
Hans de Goede c8dfc6
 static inline bool ehci_enabled(EHCIState *s)
Hans de Goede c8dfc6
 {
Hans de Goede c8dfc6
     return s->usbcmd & USBCMD_RUNSTOP;
Hans de Goede c8dfc6
@@ -785,27 +791,33 @@ static EHCIQueue *ehci_alloc_queue(EHCIState *ehci, uint32_t addr, int async)
Hans de Goede c8dfc6
     return q;
Hans de Goede c8dfc6
 }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-static void ehci_cancel_queue(EHCIQueue *q)
Hans de Goede c8dfc6
+static int ehci_cancel_queue(EHCIQueue *q)
Hans de Goede c8dfc6
 {
Hans de Goede c8dfc6
     EHCIPacket *p;
Hans de Goede c8dfc6
+    int packets = 0;
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     p = QTAILQ_FIRST(&q->packets);
Hans de Goede c8dfc6
     if (p == NULL) {
Hans de Goede c8dfc6
-        return;
Hans de Goede c8dfc6
+        return 0;
Hans de Goede c8dfc6
     }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     trace_usb_ehci_queue_action(q, "cancel");
Hans de Goede c8dfc6
     do {
Hans de Goede c8dfc6
         ehci_free_packet(p);
Hans de Goede c8dfc6
+        packets++;
Hans de Goede c8dfc6
     } while ((p = QTAILQ_FIRST(&q->packets)) != NULL);
Hans de Goede c8dfc6
+    return packets;
Hans de Goede c8dfc6
 }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-static void ehci_reset_queue(EHCIQueue *q)
Hans de Goede c8dfc6
+static int ehci_reset_queue(EHCIQueue *q)
Hans de Goede c8dfc6
 {
Hans de Goede c8dfc6
+    int packets;
Hans de Goede c8dfc6
+
Hans de Goede c8dfc6
     trace_usb_ehci_queue_action(q, "reset");
Hans de Goede c8dfc6
-    ehci_cancel_queue(q);
Hans de Goede c8dfc6
+    packets = ehci_cancel_queue(q);
Hans de Goede c8dfc6
     q->dev = NULL;
Hans de Goede c8dfc6
     q->qtdaddr = 0;
Hans de Goede c8dfc6
+    return packets;
Hans de Goede c8dfc6
 }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
 static void ehci_free_queue(EHCIQueue *q)
Hans de Goede c8dfc6
@@ -1817,7 +1829,9 @@ static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async)
Hans de Goede c8dfc6
         (memcmp(&qh.current_qtd, &q->qh.current_qtd,
Hans de Goede c8dfc6
                                  9 * sizeof(uint32_t)) != 0) ||
Hans de Goede c8dfc6
         (q->dev != NULL && q->dev->addr != devaddr)) {
Hans de Goede c8dfc6
-        ehci_reset_queue(q);
Hans de Goede c8dfc6
+        if (ehci_reset_queue(q) > 0) {
Hans de Goede c8dfc6
+            ehci_trace_guest_bug(ehci, "guest updated active QH");
Hans de Goede c8dfc6
+        }
Hans de Goede c8dfc6
         p = NULL;
Hans de Goede c8dfc6
     }
Hans de Goede c8dfc6
     q->qh = qh;
Hans de Goede c8dfc6
@@ -1979,8 +1993,8 @@ static int ehci_state_fetchqtd(EHCIQueue *q)
Hans de Goede c8dfc6
             (!NLPTR_TBIT(p->qtd.next) && (p->qtd.next != qtd.next)) ||
Hans de Goede c8dfc6
             (!NLPTR_TBIT(p->qtd.altnext) && (p->qtd.altnext != qtd.altnext)) ||
Hans de Goede c8dfc6
             p->qtd.bufptr[0] != qtd.bufptr[0]) {
Hans de Goede c8dfc6
-            /* guest bug: guest updated active QH or qTD underneath us */
Hans de Goede c8dfc6
             ehci_cancel_queue(q);
Hans de Goede c8dfc6
+            ehci_trace_guest_bug(q->ehci, "guest updated active QH or qTD");
Hans de Goede c8dfc6
             p = NULL;
Hans de Goede c8dfc6
         } else {
Hans de Goede c8dfc6
             p->qtd = qtd;
Hans de Goede c8dfc6
diff --git a/trace-events b/trace-events
Hans de Goede c8dfc6
index 8fcbc50..5112a47 100644
Hans de Goede c8dfc6
--- a/trace-events
Hans de Goede c8dfc6
+++ b/trace-events
Hans de Goede c8dfc6
@@ -263,6 +263,7 @@ usb_ehci_data(int rw, uint32_t cpage, uint32_t offset, uint32_t addr, uint32_t l
Hans de Goede c8dfc6
 usb_ehci_queue_action(void *q, const char *action) "q %p: %s"
Hans de Goede c8dfc6
 usb_ehci_packet_action(void *q, void *p, const char *action) "q %p p %p: %s"
Hans de Goede c8dfc6
 usb_ehci_irq(uint32_t level, uint32_t frindex, uint32_t sts, uint32_t mask) "level %d, frindex 0x%04x, sts 0x%x, mask 0x%x"
Hans de Goede c8dfc6
+usb_ehci_guest_bug(const char *reason) "%s"
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
 # hw/usb/hcd-uhci.c
Hans de Goede c8dfc6
 usb_uhci_reset(void) "=== RESET ==="
Hans de Goede c8dfc6
-- 
5544c1
1.7.12.1
Hans de Goede c8dfc6