In VHOST_USER_SET_VRING_ADDR handling, don't invalidate the vring
if it has already been mapped and new addresses are identical.

When initiating live-migration, VHOST_USER_SET_VRING_ADDR is sent
again by QEMU, but the queues are enabled, so invalidating them
can result in NULL pointer de-referencing. In this case, it is
not needed to perform the invalidation, as the new addresses provided
by QEMU are indentical to the initial ones.

Fixes: eefac9536a90 ("vhost: postpone device creation until rings are mapped")
Cc: sta...@dpdk.org

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

diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 4b03dbbca..29a431687 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -436,6 +436,14 @@ translate_ring_addresses(struct virtio_net *dev, int 
vq_index)
        return dev;
 }
 
+static int
+is_same_vring_addrs(struct vhost_vring_addr *a1, struct vhost_vring_addr *a2)
+{
+       return ((a1->desc_user_addr == a2->desc_user_addr) &&
+                       (a1->used_user_addr == a2->used_user_addr) &&
+                       (a1->avail_user_addr == a2->avail_user_addr));
+}
+
 /*
  * The virtio device sends us the desc, used and avail ring addresses.
  * This function then converts these to our address space.
@@ -453,6 +461,13 @@ vhost_user_set_vring_addr(struct virtio_net **pdev, 
VhostUserMsg *msg)
        /* addr->index refers to the queue index. The txq 1, rxq is 0. */
        vq = dev->virtqueue[msg->payload.addr.index];
 
+       /*
+        * If it is trying to set the same rings addresses, don't invalidate as
+        * PMD threads might be using them.
+        */
+       if (is_same_vring_addrs(addr, &vq->ring_addrs))
+               return 0;
+
        /*
         * Rings addresses should not be interpreted as long as the ring is not
         * started and enabled
-- 
2.14.3

Reply via email to