When the guest driver driver does not initialize all the queues,
QEMU currently sends SET_VRING_ADDR request for these queues.
In this case all the desc, avail and used addresses have GPA 0,
so translating them likely succeed.

The problem is that even if the uninitialized queues remain
disabled, the host application may request to disable the
notifications using rte_vhost_enable_guest_notification().
Doing this results in writing 0 to the used ring flag field,
so resulting in writing 0 in the guest physical address 0.

This patch adds a check to ensure all the ring addresses are
different before their translation.

have been negotiated, the uninitialized queues will be removed
when driver sets the DRIVER_OK status bit.
Otherwise, the port will never start to avoid any guest memory

Signed-off-by: Maxime Coquelin <maxime.coque...@redhat.com>
 lib/librte_vhost/vhost_user.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 7ab02c44b..ad4d16492 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -448,6 +448,19 @@ translate_ring_addresses(struct virtio_net *dev, int 
        if (vq->desc && vq->avail && vq->used)
                return dev;
+       /*
+        * QEMU currently sends SET_VRING_ADDR request even for queues
+        * not initialized by the guest driver. In this case, all rings
+        * addresses are identical (GPA 0).
+        */
+       if (addr->desc_user_addr == addr->avail_user_addr &&
+                       addr->desc_user_addr == addr->used_user_addr) {
+               RTE_LOG(INFO, VHOST_CONFIG,
+                               "Invalid rings addresses for dev %d queue %d\n",
+                               dev->vid, vq_index);
+               return dev;
+       }
        vq->desc = (struct vring_desc *)(uintptr_t)ring_addr_to_vva(dev,
                        vq, addr->desc_user_addr, sizeof(struct vring_desc));
        if (vq->desc == 0) {

Reply via email to