From: Xiantao Zhang <[email protected]> ia64 depends on platform provides synced idcache after DMA operation. For virtual dma operations in qemu, it also need to provide similar machanism.
Signed-off-by: Xiantao Zhang <[email protected]> Signed-off-by: Avi Kivity <[email protected]> diff --git a/qemu/cache-utils.h b/qemu/cache-utils.h index b45fde4..2a07fbd 100644 --- a/qemu/cache-utils.h +++ b/qemu/cache-utils.h @@ -33,8 +33,22 @@ static inline void flush_icache_range(unsigned long start, unsigned long stop) asm volatile ("sync" : : : "memory"); asm volatile ("isync" : : : "memory"); } +#define qemu_sync_idcache flush_icache_range +#else +#ifdef __ia64__ +static inline void qemu_sync_idcache(unsigned long start, unsigned long stop) +{ + while (start < stop) { + asm volatile ("fc %0" :: "r"(start)); + start += 32; + } + asm volatile (";;sync.i;;srlz.i;;"); +} #else +static inline void qemu_sync_idcache(unsigned long start, unsigned long stop) {} +#endif + #define qemu_cache_utils_init(envp) do { (void) (envp); } while (0) #endif diff --git a/qemu/cutils.c b/qemu/cutils.c index 5b36cc6..4bf4fcd 100644 --- a/qemu/cutils.c +++ b/qemu/cutils.c @@ -23,6 +23,7 @@ */ #include "qemu-common.h" #include "host-utils.h" +#include "cache-utils.h" #include <assert.h> void pstrcpy(char *buf, int buf_size, const char *str) @@ -215,6 +216,8 @@ 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); + qemu_sync_idcache((unsigned long)qiov->iov[i].iov_base, + (unsigned long)(qiov->iov[i].iov_base + copy)); p += copy; count -= copy; } diff --git a/qemu/dma-helpers.c b/qemu/dma-helpers.c index f9eb224..f71ca3b 100644 --- a/qemu/dma-helpers.c +++ b/qemu/dma-helpers.c @@ -9,6 +9,7 @@ #include "dma.h" #include "block_int.h" +#include "cache-utils.h" static AIOPool dma_aio_pool; @@ -137,6 +138,8 @@ static BlockDriverAIOCB *dma_bdrv_io( BlockDriverCompletionFunc *cb, void *opaque, int is_write) { + int i; + QEMUIOVector *qiov; DMAAIOCB *dbs = qemu_aio_get_pool(&dma_aio_pool, bs, cb, opaque); dbs->acb = NULL; @@ -149,6 +152,15 @@ static BlockDriverAIOCB *dma_bdrv_io( dbs->bh = NULL; qemu_iovec_init(&dbs->iov, sg->nsg); dma_bdrv_cb(dbs, 0); + + if (!is_write) { + qiov = &dbs->iov; + for (i = 0; i < qiov->niov; ++i) { + qemu_sync_idcache((unsigned long)qiov->iov[i].iov_base, + (unsigned long)(qiov->iov[i].iov_base + qiov->iov[i].iov_len)); + } + } + if (!dbs->acb) { qemu_aio_release(dbs); return NULL; diff --git a/qemu/exec.c b/qemu/exec.c index cc2eb04..2cb71df 100644 --- a/qemu/exec.c +++ b/qemu/exec.c @@ -3247,6 +3247,9 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len, addr1 += l; access_len -= l; } + if (kvm_enabled()) + flush_icache_range((unsigned long)buffer, + (unsigned long)buffer + access_len); } return; } -- To unsubscribe from this list: send the line "unsubscribe kvm-commits" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
