On 24.07.26 00:30, 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 then it line with DMAMap and iova-tree
convention.
Signed-off-by: Connor Kite <[email protected]>
---
hw/virtio/vhost-shadow-virtqueue.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/virtio/vhost-shadow-virtqueue.c
b/hw/virtio/vhost-shadow-virtqueue.c
index 9e3c359f50..20e5c7d2f1 100644
--- a/hw/virtio/vhost-shadow-virtqueue.c
+++ b/hw/virtio/vhost-shadow-virtqueue.c
@@ -104,14 +104,14 @@ static bool vhost_svq_translate_addr(const
VhostShadowVirtqueue *svq,
/* 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);
}
It’s not immediately obvious what is ensuring that `iov_len` can never
be 0. Sure, it would be wrong and makes no sense, but that is why I
think an `assert(iovec[i].iov_len > 0)` would be appropriate.
(Looks like `virtqueue_map_desc()` is what rejects zero length, but that
is not really local to this code path, so not immediately obvious.)
Hanna