]> xenbits.xensource.com Git - qemu-xen-4.2-testing.git/commitdiff
usb-ohci: td.cbp incorrectly updated near page end
authorAndriy Gapon <avg@FreeBSD.org>
Thu, 22 Dec 2011 09:34:30 +0000 (11:34 +0200)
committerGerd Hoffmann <kraxel@redhat.com>
Fri, 6 Jan 2012 11:36:14 +0000 (12:36 +0100)
The current code that updates the cbp value after a transfer looks like this:
td.cbp += ret;
if ((td.cbp & 0xfff) + ret > 0xfff) {
<handle page overflow>
because the 'ret' value is effectively added twice the check may fire too early
when the overflow hasn't happened yet.

Below is one of the possible changes that correct the behavior:

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
hw/usb-ohci.c

index e68be70b15356d984269ec9b72db4ee66c0556d5..81488c48e21234dd32af46ebcb9bff2c35230129 100644 (file)
@@ -1025,10 +1025,10 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
         if (ret == len) {
             td.cbp = 0;
         } else {
-            td.cbp += ret;
             if ((td.cbp & 0xfff) + ret > 0xfff) {
-                td.cbp &= 0xfff;
-                td.cbp |= td.be & ~0xfff;
+                td.cbp = (td.be & ~0xfff) + ((td.cbp + ret) & 0xfff);
+            } else {
+                td.cbp += ret;
             }
         }
         td.flags |= OHCI_TD_T1;