On 2026/08/18 8:31, Connor Kite wrote:
iova-tree expects inclusive range sizing when maps are allocated or searched.
Currently, svqs use exclusive sizing when searching their
vhost-iova-tree for a match to the region to be translated.  This could
lead to errors if the region to be translated is at the edge of an iova
region.

Fix this by reducing `needle.size` by 1 in
vhost_svq_translate_addr to bring it in line with DMAMap and iova-tree
convention.

The only current user of svq->iova_tree is hw/virtio/vhost-vdpa.c, which
also treats size as inclusive when using the tree API.  In progress work
on vhost-user isolation mode in hw/virtio.vhost-vdpa.c also uses
inclusive sizing when interacting with the tree.

Please correct hw/virtio.vhost-vdpa.c to hw/virtio/vhost-user.c. The former does not exist and misidentifies where the vhost-user isolation work lives.


This patch is an updated version of one from the patch series "vhost-user:
isolated memory".  The patch has been isolated from the series as it
is not tightly coupled with the rest of the series.

Signed-off-by: Connor Kite <[email protected]>
Reviewed-by: Stefan Hajnoczi <[email protected]>

Please add the required trailer:

    Fixes: 34e3c94edaef ("vdpa: Add custom IOTLB translations to SVQ").

That commit introduced the oversized needle, and QEMU policy requests a
Fixes: trailer for in-tree regressions.

Regards,
Akihiko Odaki

---
V2 Differences:
- Context added about users of svq->iova_tree and their adoption of
   inclusive sizing

  hw/virtio/vhost-shadow-virtqueue.c | 10 ++++++++--
  1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/vhost-shadow-virtqueue.c 
b/hw/virtio/vhost-shadow-virtqueue.c
index bcb7f2ffc7..c8831d52be 100644
--- a/hw/virtio/vhost-shadow-virtqueue.c
+++ b/hw/virtio/vhost-shadow-virtqueue.c
@@ -99,19 +99,25 @@ static bool vhost_svq_translate_addr(const 
VhostShadowVirtqueue *svq,
          const DMAMap *map;
          DMAMap needle;
+ if (unlikely(iovec[i].iov_len == 0)) {
+            qemu_log_mask(LOG_GUEST_ERROR,
+                          "Zero-sized buffer made available by guest");
+            return false;
+        }
+
          /* Check if the descriptor is backed by guest memory  */
          if (gpas) {
              /* Search the GPA->IOVA tree */
              needle = (DMAMap) {
                  .translated_addr = gpas[i],
-                .size = iovec[i].iov_len,
+                .size = iovec[i].iov_len - 1,  /* Inclusive */
              };
              map = vhost_iova_tree_find_gpa(svq->iova_tree, &needle);
          } else {
              /* Search the IOVA->HVA tree */
              needle = (DMAMap) {
                  .translated_addr = (hwaddr)(uintptr_t)iovec[i].iov_base,
-                .size = iovec[i].iov_len,
+                .size = iovec[i].iov_len - 1, /* Inclusive */
              };
              map = vhost_iova_tree_find_iova(svq->iova_tree, &needle);
          }


Reply via email to