On Mon, Aug 17, 2026 at 04:31:47PM -0700, 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.

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]>
---
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 */
                                               ^
nit: double spaces here...

            };
            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 */
                                               ^
... single here.
If you need to respin, maybe we can be consistent and fix it.

Anyway with Akihiko's comments fixed:

Reviewed-by: Stefano Garzarella <[email protected]>

Thanks for the fix!
Stefano


Reply via email to