]> git.proxmox.com Git - qemu.git/commitdiff
ehci: Verify guest does not change the token of inflight qtd-s
authorHans de Goede <hdegoede@redhat.com>
Fri, 14 Dec 2012 13:35:24 +0000 (14:35 +0100)
committerGerd Hoffmann <kraxel@redhat.com>
Mon, 7 Jan 2013 11:57:23 +0000 (12:57 +0100)
This is not allowed, except for clearing active on cancellation, so don't
warn when the new token does not have its active bit set.

This unifies the cancellation path for modified qtd-s, and prepares
ehci_verify_qtd to be used ad an extra check inside
ehci_writeback_async_complete_packet().

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
hw/usb/hcd-ehci.c

index 0d315971a95b37d6ee0e31dd0040c9df341fe4af..04301ce1733f9b0597ba8da56ccd9e49d80b50c0 100644 (file)
@@ -461,6 +461,7 @@ static bool ehci_verify_qtd(EHCIPacket *p, EHCIqtd *qtd)
         (p->queue->async && !NLPTR_TBIT(p->qtd.next) &&
             (p->qtd.next != qtd->next)) ||
         (!NLPTR_TBIT(p->qtd.altnext) && (p->qtd.altnext != qtd->altnext)) ||
+        p->qtd.token != qtd->token ||
         p->qtd.bufptr[0] != qtd->bufptr[0]) {
         return false;
     } else {
@@ -1793,7 +1794,9 @@ static int ehci_state_fetchqtd(EHCIQueue *q)
     if (p != NULL) {
         if (!ehci_verify_qtd(p, &qtd)) {
             ehci_cancel_queue(q);
-            ehci_trace_guest_bug(q->ehci, "guest updated active QH or qTD");
+            if (qtd.token & QTD_TOKEN_ACTIVE) {
+                ehci_trace_guest_bug(q->ehci, "guest updated active qTD");
+            }
             p = NULL;
         } else {
             p->qtd = qtd;
@@ -1802,11 +1805,6 @@ static int ehci_state_fetchqtd(EHCIQueue *q)
     }
 
     if (!(qtd.token & QTD_TOKEN_ACTIVE)) {
-        if (p != NULL) {
-            /* transfer canceled by guest (clear active) */
-            ehci_cancel_queue(q);
-            p = NULL;
-        }
         ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
     } else if (p != NULL) {
         switch (p->async) {