]> xenbits.xen.org Git - xenclient/ioemu.git/commitdiff
Fix DMA emualtion for ia64.
authorIan Jackson <ian.jackson@eu.citrix.com>
Fri, 8 May 2009 16:26:01 +0000 (17:26 +0100)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Fri, 8 May 2009 16:26:01 +0000 (17:26 +0100)
For DMA in native system, operating system depends on platform
flushes icache of memory touched by DMA operations.
But as to virtual DMA of virtual machine, dma emulation code has to
use explicit instructions to flush icahce,otherwise,
guest may use old icache and leads to guest's crash.

Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
Signed-off-by: Yang Zhang <yang.zhang@intel.com>
cache-utils.h
cutils.c
dma-helpers.c

index b45fde44e85490c981006e48fb10613d6d06e6d0..561d2517b40b8e7ef0585c02e0380beda85db1f9 100644 (file)
@@ -34,8 +34,20 @@ static inline void flush_icache_range(unsigned long start, unsigned long stop)
     asm volatile ("isync" : : : "memory");
 }
 
+#elif defined (__ia64__)
+static inline void flush_icache_range(unsigned long start, unsigned long stop)
+{
+    while (start < stop) {
+           asm volatile ("fc %0" :: "r"(start));
+           start += 32;
+    }
+    asm volatile (";;sync.i;;srlz.i;;");
+}
+
+#define qemu_cache_utils_init(envp) do { (void) (envp); } while (0)
 #else
 #define qemu_cache_utils_init(envp) do { (void) (envp); } while (0)
 #endif
 
+
 #endif /* QEMU_CACHE_UTILS_H */
index 4541214db709b98ceff666538e7f6a9ba5dd341c..5137fe13cf229ff674d5ad64c54d8618cde62faa 100644 (file)
--- a/cutils.c
+++ b/cutils.c
@@ -23,6 +23,7 @@
  */
 #include "qemu-common.h"
 #include "host-utils.h"
+#include "cache-utils.h"
 
 void pstrcpy(char *buf, size_t buf_size, const char *str)
 {
@@ -157,6 +158,12 @@ void qemu_iovec_from_buffer(QEMUIOVector *qiov, const void *buf, size_t count)
         if (copy > qiov->iov[i].iov_len)
             copy = qiov->iov[i].iov_len;
         memcpy(qiov->iov[i].iov_base, p, copy);
+
+#ifdef __ia64__
+        flush_icache_range((unsigned long)qiov->iov[i].iov_base,
+                  (unsigned long)(qiov->iov[i].iov_base + copy));
+#endif
+
         p     += copy;
         count -= copy;
     }
index b2ade19acb1958b334b49d1a787902dbac39295e..0523dc8d29df69f67d90fe309b25ca3bbd009866 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "dma.h"
 #include "block_int.h"
+#include "cache-utils.h"
 
 void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint)
 {
@@ -135,6 +136,19 @@ static BlockDriverAIOCB *dma_bdrv_io(
     dbs->bh = NULL;
     qemu_iovec_init(&dbs->iov, sg->nsg);
     dma_bdrv_cb(dbs, 0);
+
+#ifdef __ia64__
+    if (!is_write) {
+       int i;
+       QEMUIOVector *qiov;
+        qiov = &dbs->iov;
+        for (i = 0; i < qiov->niov; ++i) {
+           flush_icache_range((unsigned long)qiov->iov[i].iov_base,
+                 (unsigned long)(qiov->iov[i].iov_base + qiov->iov[i].iov_len));
+       }
+    }
+#endif
+
     return dbs->acb;
 }