This patch fixes the used ring address calculation, to
avoid Vhost-vDPA backends (such as VDUSE) to fail while
trying to translate it.

Fixes: 666ef294ddf7 ("net/virtio-user: share descriptor IOVA to backend")
Cc: [email protected]

Reported-by: Adrian Moreno <[email protected]>
Signed-off-by: Maxime Coquelin <[email protected]>
---

Changes in v2:
- Refactor addresses calculation (David)

---


 .../net/virtio/virtio_user/virtio_user_dev.c  | 30 ++++++++-----------
 1 file changed, 13 insertions(+), 17 deletions(-)

diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c 
b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index 187f81b066..f3df73c1f0 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -118,7 +118,7 @@ virtio_user_kick_queue(struct virtio_user_dev *dev, 
uint32_t queue_sel)
        struct vhost_vring_state state;
        struct vring *vring = &dev->vrings.split[queue_sel];
        struct vring_packed *pq_vring = &dev->vrings.packed[queue_sel];
-       uint64_t desc_addr, avail_addr, used_addr;
+       uint64_t desc_addr, desc_iova_addr, avail_addr, used_addr;
        struct vhost_vring_addr addr = {
                .index = queue_sel,
                .log_guest_addr = 0,
@@ -138,25 +138,21 @@ virtio_user_kick_queue(struct virtio_user_dev *dev, 
uint32_t queue_sel)
        }

        if (dev->features & (1ULL << VIRTIO_F_RING_PACKED)) {
-               desc_addr = pq_vring->desc_iova;
-               avail_addr = desc_addr + pq_vring->num * sizeof(struct 
vring_packed_desc);
-               used_addr =  RTE_ALIGN_CEIL(avail_addr + sizeof(struct 
vring_packed_desc_event),
-                                           VIRTIO_VRING_ALIGN);
-
-               addr.desc_user_addr = desc_addr;
-               addr.avail_user_addr = avail_addr;
-               addr.used_user_addr = used_addr;
+               desc_iova_addr = pq_vring->desc_iova;
+               desc_addr = (uint64_t)(uintptr_t)pq_vring->desc;
+               avail_addr = (uint64_t)(uintptr_t)pq_vring->driver;
+               used_addr = (uint64_t)(uintptr_t)pq_vring->device;
        } else {
-               desc_addr = vring->desc_iova;
-               avail_addr = desc_addr + vring->num * sizeof(struct vring_desc);
-               used_addr = 
RTE_ALIGN_CEIL((uintptr_t)(&vring->avail->ring[vring->num]),
-                                          VIRTIO_VRING_ALIGN);
-
-               addr.desc_user_addr = desc_addr;
-               addr.avail_user_addr = avail_addr;
-               addr.used_user_addr = used_addr;
+               desc_iova_addr = vring->desc_iova;
+               desc_addr = (uint64_t)(uintptr_t)vring->desc;
+               avail_addr = (uint64_t)(uintptr_t)vring->avail;
+               used_addr = (uint64_t)(uintptr_t)vring->used;
        }

+       addr.desc_user_addr = desc_iova_addr;
+       addr.avail_user_addr = (desc_iova_addr - desc_addr) + avail_addr;
+       addr.used_user_addr = (desc_iova_addr - desc_addr) + used_addr;
+
        state.index = queue_sel;
        state.num = vring->num;
        ret = dev->ops->set_vring_num(dev, &state);
--
2.51.0

Reply via email to