summaryrefslogtreecommitdiffstats
path: root/dma-helpers.c
diff options
context:
space:
mode:
authorPeter Maydell2020-06-18 13:15:33 +0200
committerPeter Maydell2020-06-18 13:15:33 +0200
commit3b268766ecb7b630938e9bfb89b106a9dd8d94ae (patch)
tree5a2461177da2d2777dee96773e1e5ce367c35195 /dma-helpers.c
parentMerge remote-tracking branch 'remotes/kraxel/tags/microvm-20200617-pull-reque... (diff)
parentiotests: Add copyright line in qcow2.py (diff)
downloadqemu-3b268766ecb7b630938e9bfb89b106a9dd8d94ae.tar.gz
qemu-3b268766ecb7b630938e9bfb89b106a9dd8d94ae.tar.xz
qemu-3b268766ecb7b630938e9bfb89b106a9dd8d94ae.zip
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches: - enhance handling of size-related BlockConf properties - nvme: small fixes, refactoring and cleanups - virtio-blk: On restart, process queued requests in the proper context - icount: make dma reads deterministic - iotests: Some fixes for rarely run cases - .gitignore: Ignore storage-daemon files - Minor code cleanups # gpg: Signature made Wed 17 Jun 2020 15:47:19 BST # gpg: using RSA key DC3DEB159A9AF95D3D7456FE7F09B272C88F2FD6 # gpg: issuer "kwolf@redhat.com" # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full] # Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6 * remotes/kevin/tags/for-upstream: (43 commits) iotests: Add copyright line in qcow2.py iotests/{190,291}: compat=0.10 is unsupported iotests/229: data_file is unsupported iotests/292: data_file is unsupported iotests/041: Skip test_small_target for qed iotests.py: Add skip_for_formats() decorator block: lift blocksize property limit to 2 MiB qdev-properties: add getter for size32 and blocksize block: make BlockConf size props 32bit and accept size suffixes qdev-properties: make blocksize accept size suffixes qdev-properties: add size32 property type qdev-properties: blocksize: use same limits in code and description block: consolidate blocksize properties consistency checks virtio-blk: store opt_io_size with correct size .gitignore: Ignore storage-daemon files hw/block/nvme: verify msix_init_exclusive_bar() return value hw/block/nvme: add msix_qsize parameter hw/block/nvme: Verify msix_vector_use() returned value hw/block/nvme: factor out controller identify setup hw/block/nvme: do cmb/pmr init as part of pci init ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'dma-helpers.c')
-rw-r--r--dma-helpers.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/dma-helpers.c b/dma-helpers.c
index e8a26e81e1..2a77b5a9cb 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -13,6 +13,8 @@
#include "trace-root.h"
#include "qemu/thread.h"
#include "qemu/main-loop.h"
+#include "sysemu/cpus.h"
+#include "qemu/range.h"
/* #define DEBUG_IOMMU */
@@ -142,6 +144,26 @@ static void dma_blk_cb(void *opaque, int ret)
cur_addr = dbs->sg->sg[dbs->sg_cur_index].base + dbs->sg_cur_byte;
cur_len = dbs->sg->sg[dbs->sg_cur_index].len - dbs->sg_cur_byte;
mem = dma_memory_map(dbs->sg->as, cur_addr, &cur_len, dbs->dir);
+ /*
+ * Make reads deterministic in icount mode. Windows sometimes issues
+ * disk read requests with overlapping SGs. It leads
+ * to non-determinism, because resulting buffer contents may be mixed
+ * from several sectors. This code splits all SGs into several
+ * groups. SGs in every group do not overlap.
+ */
+ if (mem && use_icount && dbs->dir == DMA_DIRECTION_FROM_DEVICE) {
+ int i;
+ for (i = 0 ; i < dbs->iov.niov ; ++i) {
+ if (ranges_overlap((intptr_t)dbs->iov.iov[i].iov_base,
+ dbs->iov.iov[i].iov_len, (intptr_t)mem,
+ cur_len)) {
+ dma_memory_unmap(dbs->sg->as, mem, cur_len,
+ dbs->dir, cur_len);
+ mem = NULL;
+ break;
+ }
+ }
+ }
if (!mem)
break;
qemu_iovec_add(&dbs->iov, mem, cur_len);