qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Jason Wang <jasowang@redhat.com>
To: mst@redhat.com
Cc: qemu-devel@nongnu.org, Jason Wang <jasowang@redhat.com>,
	qemu-stable@nongnu.org, Yalan Zhang <yalzhang@redhat.com>,
	Eric Auger <eric.auger@redhat.com>, Lei Yang <leiyang@redhat.com>
Subject: [PATCH for 7.2?] vhost: fix vq dirt bitmap syncing when vIOMMU is enabled
Date: Tue, 22 Nov 2022 11:01:11 +0800	[thread overview]
Message-ID: <20221122030111.4230-1-jasowang@redhat.com> (raw)

When vIOMMU is enabled, the vq->used_phys is actually the IOVA not
GPA. So we need to translate it to GPA before the syncing otherwise we
may hit the following crash since IOVA could be out of the scope of
the GPA log size. This could be noted when using virtio-IOMMU with
vhost using 1G memory.

Fixes: c471ad0e9bd46 ("vhost_net: device IOTLB support")
Cc: qemu-stable@nongnu.org
Reported-by: Yalan Zhang <yalzhang@redhat.com>
Tested-by: Eric Auger <eric.auger@redhat.com>
Tested-by: Lei Yang <leiyang@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 hw/virtio/vhost.c | 65 ++++++++++++++++++++++++++++++++---------------
 1 file changed, 45 insertions(+), 20 deletions(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index d1c4c20b8c..26b319f34e 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -106,11 +106,30 @@ static void vhost_dev_sync_region(struct vhost_dev *dev,
     }
 }
 
+static bool vhost_dev_has_iommu(struct vhost_dev *dev)
+{
+    VirtIODevice *vdev = dev->vdev;
+
+    /*
+     * For vhost, VIRTIO_F_IOMMU_PLATFORM means the backend support
+     * incremental memory mapping API via IOTLB API. For platform that
+     * does not have IOMMU, there's no need to enable this feature
+     * which may cause unnecessary IOTLB miss/update transactions.
+     */
+    if (vdev) {
+        return virtio_bus_device_iommu_enabled(vdev) &&
+            virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
+    } else {
+        return false;
+    }
+}
+
 static int vhost_sync_dirty_bitmap(struct vhost_dev *dev,
                                    MemoryRegionSection *section,
                                    hwaddr first,
                                    hwaddr last)
 {
+    IOMMUTLBEntry iotlb;
     int i;
     hwaddr start_addr;
     hwaddr end_addr;
@@ -132,13 +151,37 @@ static int vhost_sync_dirty_bitmap(struct vhost_dev *dev,
     }
     for (i = 0; i < dev->nvqs; ++i) {
         struct vhost_virtqueue *vq = dev->vqs + i;
+        hwaddr used_phys = vq->used_phys, used_size = vq->used_size;
+        hwaddr phys, s;
 
         if (!vq->used_phys && !vq->used_size) {
             continue;
         }
 
-        vhost_dev_sync_region(dev, section, start_addr, end_addr, vq->used_phys,
-                              range_get_last(vq->used_phys, vq->used_size));
+        if (vhost_dev_has_iommu(dev)) {
+            while (used_size) {
+                rcu_read_lock();
+                iotlb = address_space_get_iotlb_entry(dev->vdev->dma_as,
+                                                      used_phys,
+                                                      true, MEMTXATTRS_UNSPECIFIED);
+                rcu_read_unlock();
+
+                if (iotlb.target_as == NULL) {
+                    return -EINVAL;
+                }
+
+                phys = iotlb.translated_addr;
+                s = MIN(iotlb.addr_mask + 1, used_size);
+
+                vhost_dev_sync_region(dev, section, start_addr, end_addr, phys,
+                                      range_get_last(phys, used_size));
+                used_size -= s;
+                used_phys += s;
+            }
+        } else {
+            vhost_dev_sync_region(dev, section, start_addr, end_addr, used_phys,
+                                  range_get_last(used_phys, used_size));
+        }
     }
     return 0;
 }
@@ -306,24 +349,6 @@ static inline void vhost_dev_log_resize(struct vhost_dev *dev, uint64_t size)
     dev->log_size = size;
 }
 
-static bool vhost_dev_has_iommu(struct vhost_dev *dev)
-{
-    VirtIODevice *vdev = dev->vdev;
-
-    /*
-     * For vhost, VIRTIO_F_IOMMU_PLATFORM means the backend support
-     * incremental memory mapping API via IOTLB API. For platform that
-     * does not have IOMMU, there's no need to enable this feature
-     * which may cause unnecessary IOTLB miss/update transactions.
-     */
-    if (vdev) {
-        return virtio_bus_device_iommu_enabled(vdev) &&
-            virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
-    } else {
-        return false;
-    }
-}
-
 static void *vhost_memory_map(struct vhost_dev *dev, hwaddr addr,
                               hwaddr *plen, bool is_write)
 {
-- 
2.25.1



             reply	other threads:[~2022-11-22  3:02 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-22  3:01 Jason Wang [this message]
2022-11-22  9:43 ` [PATCH for 7.2?] vhost: fix vq dirt bitmap syncing when vIOMMU is enabled Michael S. Tsirkin
2022-11-22 16:28   ` Eric Auger
2022-11-23  5:26     ` Jason Wang
2022-11-23  5:47       ` Jason Wang
2022-11-23  6:15         ` Michael S. Tsirkin
2022-11-23  7:08           ` Jason Wang
2022-11-23  7:21             ` Michael S. Tsirkin
2022-11-24  4:12               ` Jason Wang
2022-11-24  7:06                 ` Michael S. Tsirkin
2022-11-24  7:31                   ` Jason Wang
2022-11-24  7:41                     ` Michael S. Tsirkin
2022-11-24  7:58                       ` Jason Wang

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=20221122030111.4230-1-jasowang@redhat.com \
    --to=jasowang@redhat.com \
    --cc=eric.auger@redhat.com \
    --cc=leiyang@redhat.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-stable@nongnu.org \
    --cc=yalzhang@redhat.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).