All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Cc: Wei Yang <weiyang@linux.vnet.ibm.com>,
	Gerd Hoffman <kraxel@redhat.com>,
	David Gibson <david@gibson.dropbear.id.au>
Subject: [Qemu-devel] [PATCH 04/14] usb-ohci: DMA writeback bug fixes
Date: Tue, 13 Mar 2012 13:20:01 +0100	[thread overview]
Message-ID: <1331641211-20077-5-git-send-email-kraxel@redhat.com> (raw)
In-Reply-To: <1331641211-20077-1-git-send-email-kraxel@redhat.com>

From: Wei Yang <weiyang@linux.vnet.ibm.com>

This patch fixes two bugs in the OHCI device where the device writes
back data to system memory that should be exclusively under the
control of the guest side driver.

In OHCI specification Section 5.2.7, it mentioned "In all cases, Host
Controller Driver is responsible for the insertion and removal of all
Endpoint Descriptors in the various Host Controller Endpoint
Descriptor lists".  In the ohci_frame_boundary(), ohci_put_hcca()
writes the entire hcca back including the interrupt ED lists which
should be under driver control. This violates the specification and
can race with a host driver updating that list at the same time.

In the OHCI Spec Section 4.6, Transfer Descriptor Queue Processing, it
mentioned "Since the TD pointed to by TailP is not accessed by the HC,
the Host Controller Driver can initialize that TD and link at least
one other to it without creating a coherency or synchronization
problem".  While the function ohci_put_ed() writes the entire endpoint
descriptor back including the TailP which should under driver
control. This violate the specification and can race with a host
driver updating the TD list at the same time.

In each case the solution is to make sure we don't write data which is
under driver control.

Cc: Gerd Hoffman <kraxel@redhat.com>

Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb/hcd-ohci.c |   17 +++++++++++++++--
 1 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index 51fa111..1a1cc88 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -121,6 +121,11 @@ struct ohci_hcca {
     uint16_t frame, pad;
     uint32_t done;
 };
+#define HCCA_WRITEBACK_OFFSET   offsetof(struct ohci_hcca, frame)
+#define HCCA_WRITEBACK_SIZE     8 /* frame, pad, done */
+
+#define ED_WBACK_OFFSET offsetof(struct ohci_ed, head)
+#define ED_WBACK_SIZE   4
 
 static void ohci_bus_stop(OHCIState *ohci);
 static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev);
@@ -568,7 +573,13 @@ static inline int ohci_read_hcca(OHCIState *ohci,
 static inline int ohci_put_ed(OHCIState *ohci,
                               uint32_t addr, struct ohci_ed *ed)
 {
-    return put_dwords(ohci, addr, (uint32_t *)ed, sizeof(*ed) >> 2);
+    /* ed->tail is under control of the HCD.
+     * Since just ed->head is changed by HC, just write back this
+     */
+
+    return put_dwords(ohci, addr + ED_WBACK_OFFSET,
+                      (uint32_t *)((char *)ed + ED_WBACK_OFFSET),
+                      ED_WBACK_SIZE >> 2);
 }
 
 static inline int ohci_put_td(OHCIState *ohci,
@@ -587,7 +598,9 @@ static inline int ohci_put_iso_td(OHCIState *ohci,
 static inline int ohci_put_hcca(OHCIState *ohci,
                                 uint32_t addr, struct ohci_hcca *hcca)
 {
-    cpu_physical_memory_write(addr + ohci->localmem_base, hcca, sizeof(*hcca));
+    cpu_physical_memory_write(addr + ohci->localmem_base + HCCA_WRITEBACK_OFFSET,
+                              (char *)hcca + HCCA_WRITEBACK_OFFSET,
+                              HCCA_WRITEBACK_SIZE);
     return 1;
 }
 
-- 
1.7.1

  parent reply	other threads:[~2012-03-13 12:20 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-13 12:19 [Qemu-devel] [PULL 00/14] usb patch queue Gerd Hoffmann
2012-03-13 12:19 ` [Qemu-devel] [PATCH 01/14] usb: the big rename Gerd Hoffmann
2012-03-13 13:29   ` Hans de Goede
2012-03-13 12:19 ` [Qemu-devel] [PATCH 02/14] usb: zap hw/ush-{ohic, uhci}.h + init wrappers Gerd Hoffmann
2012-03-13 12:20 ` [Qemu-devel] [PATCH 03/14] usb-ehci: drop unused isoch_pause variable Gerd Hoffmann
2012-03-13 12:20 ` Gerd Hoffmann [this message]
2012-03-13 12:20 ` [Qemu-devel] [PATCH 05/14] usb: improve packet state sanity checks Gerd Hoffmann
2012-03-13 12:20 ` [Qemu-devel] [PATCH 06/14] uhci: pass addr to uhci_async_alloc Gerd Hoffmann
2012-03-13 12:20 ` [Qemu-devel] [PATCH 07/14] uhci: fix uhci_async_cancel_all Gerd Hoffmann
2012-03-13 12:20 ` [Qemu-devel] [PATCH 08/14] uhci: cancel on schedule stop Gerd Hoffmann
2012-03-13 12:20 ` [Qemu-devel] [PATCH 09/14] uhci: tracing support Gerd Hoffmann
2012-03-13 12:20 ` [Qemu-devel] [PATCH 10/14] uhci: use enum for uhci_handle_td return codes Gerd Hoffmann
2012-03-13 12:20 ` [Qemu-devel] [PATCH 11/14] uhci: renumber " Gerd Hoffmann
2012-03-13 12:20 ` [Qemu-devel] [PATCH 12/14] uhci: new uhci_handle_td return code for tds still in flight Gerd Hoffmann
2012-03-13 12:20 ` [Qemu-devel] [PATCH 13/14] uhci: alloc can't fail, drop check Gerd Hoffmann
2012-03-13 12:20 ` [Qemu-devel] [PATCH 14/14] Endian fix an assertion in usb-msd Gerd Hoffmann
2012-03-13 19:55 ` [Qemu-devel] [PULL 00/14] usb patch queue Anthony Liguori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1331641211-20077-5-git-send-email-kraxel@redhat.com \
    --to=kraxel@redhat.com \
    --cc=david@gibson.dropbear.id.au \
    --cc=qemu-devel@nongnu.org \
    --cc=weiyang@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.