|
|
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 |
|