dcavalca / rpms / qemu

Forked from rpms/qemu a year ago
Clone

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

Hans de Goede c8dfc6
From 044dcae94243d03739c309935a68b646424a4d4e 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
Hans de Goede c8dfc6
Subject: [PATCH 311/366] 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>
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
-- 
Hans de Goede c8dfc6
1.7.12
Hans de Goede c8dfc6