[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [HVM] Prevent usb driver crashes in Windows



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1181157846 -3600
# Node ID 677731eb734d8d7afa37a2e31ca2ed85fbebc2a5
# Parent  f5a71c9771a81f220926ac11e4c9a2a27530c20a
[HVM] Prevent usb driver crashes in Windows

Use atomic updates to read/write usb controller data.
This can be done because:
    a) word copies on x86 are atomic
    b) The USB spec requires word alignment

This will need to be enhanced once USB 1.2 is supported.

Signed-off-by: Steve Ofsthun <sofsthun@xxxxxxxxxxxxxxx>

Update to copy 'longword'-sized atoms.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 tools/ioemu/target-i386-dm/exec-dm.c |   29 +++++++++++++++++++++++++++--
 1 files changed, 27 insertions(+), 2 deletions(-)

diff -r f5a71c9771a8 -r 677731eb734d tools/ioemu/target-i386-dm/exec-dm.c
--- a/tools/ioemu/target-i386-dm/exec-dm.c      Wed Jun 06 17:49:39 2007 +0100
+++ b/tools/ioemu/target-i386-dm/exec-dm.c      Wed Jun 06 20:24:06 2007 +0100
@@ -437,6 +437,31 @@ extern unsigned long *logdirty_bitmap;
 extern unsigned long *logdirty_bitmap;
 extern unsigned long logdirty_bitmap_size;
 
+/*
+ * Replace the standard byte memcpy with a word memcpy for appropriately sized
+ * memory copy operations.  Some users (USB-UHCI) can not tolerate the possible
+ * word tearing that can result from a guest concurrently writing a memory
+ * structure while the qemu device model is modifying the same location.
+ * Forcing a word-sized read/write prevents the guest from seeing a partially
+ * written word-sized atom.
+ */
+void memcpy_words(void *dst, void *src, size_t n)
+{
+    while (n >= sizeof(long)) {
+        *((long *)dst)++ = *((long *)src)++;
+        n -= sizeof(long);
+    }
+
+    if (n & 4)
+        *((uint32_t *)dst)++ = *((uint32_t *)src)++;
+
+    if (n & 2)
+        *((uint16_t *)dst)++ = *((uint16_t *)src)++;
+
+    if (n & 1)
+        *((uint8_t *)dst)++ = *((uint8_t *)src)++;
+}
+
 void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, 
                             int len, int is_write)
 {
@@ -473,7 +498,7 @@ void cpu_physical_memory_rw(target_phys_
                 }
             } else if ((ptr = phys_ram_addr(addr)) != NULL) {
                 /* Writing to RAM */
-                memcpy(ptr, buf, l);
+                memcpy_words(ptr, buf, l);
                 if (logdirty_bitmap != NULL) {
                     /* Record that we have dirtied this frame */
                     unsigned long pfn = addr >> TARGET_PAGE_BITS;
@@ -509,7 +534,7 @@ void cpu_physical_memory_rw(target_phys_
                 }
             } else if ((ptr = phys_ram_addr(addr)) != NULL) {
                 /* Reading from RAM */
-                memcpy(buf, ptr, l);
+                memcpy_words(buf, ptr, l);
             } else {
                 /* Neither RAM nor known MMIO space */
                 memset(buf, 0xff, len); 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.