]> git.droids-corp.org - dpdk.git/commitdiff
vhost: add runtime locking check in unsafe API
authorMaxime Coquelin <maxime.coquelin@redhat.com>
Wed, 11 May 2022 06:58:37 +0000 (08:58 +0200)
committerMaxime Coquelin <maxime.coquelin@redhat.com>
Wed, 1 Jun 2022 09:50:09 +0000 (11:50 +0200)
This patch adds runtime checks in unsafe Vhost async APIs,
to ensure the access lock is taken.

The detection won't work every time, as another thread
could take the lock, but it would help to detect misuse
of these unsafe API.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: David Marchand <david.marchand@redhat.com>
Reviewed-by: Jiayu Hu <jiayu.hu@intel.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
lib/vhost/vhost.c
lib/vhost/virtio_net.c

index 3537680107d1478bff68bfbb21ef143f6b3be463..b14521e4d18594d44e48344bd765ec10d4ea5633 100644 (file)
@@ -1769,6 +1769,12 @@ rte_vhost_async_channel_register_thread_unsafe(int vid, uint16_t queue_id)
        if (unlikely(vq == NULL || !dev->async_copy))
                return -1;
 
+       if (unlikely(!rte_spinlock_is_locked(&vq->access_lock))) {
+               VHOST_LOG_CONFIG(ERR, "(%s) %s() called without access lock taken.\n",
+                               dev->ifname, __func__);
+               return -1;
+       }
+
        return async_channel_register(vid, queue_id);
 }
 
@@ -1829,6 +1835,12 @@ rte_vhost_async_channel_unregister_thread_unsafe(int vid, uint16_t queue_id)
        if (vq == NULL)
                return -1;
 
+       if (unlikely(!rte_spinlock_is_locked(&vq->access_lock))) {
+               VHOST_LOG_CONFIG(ERR, "(%s) %s() called without access lock taken.\n",
+                               dev->ifname, __func__);
+               return -1;
+       }
+
        if (!vq->async)
                return 0;
 
@@ -1957,6 +1969,12 @@ rte_vhost_async_get_inflight_thread_unsafe(int vid, uint16_t queue_id)
        if (vq == NULL)
                return ret;
 
+       if (unlikely(!rte_spinlock_is_locked(&vq->access_lock))) {
+               VHOST_LOG_CONFIG(ERR, "(%s) %s() called without access lock taken.\n",
+                               dev->ifname, __func__);
+               return -1;
+       }
+
        if (!vq->async)
                return ret;
 
index c8905c770a1a18de77628045128619ada7845ace..4961d390075faed4060141bfe8bec3752d085054 100644 (file)
@@ -2144,6 +2144,12 @@ rte_vhost_clear_queue_thread_unsafe(int vid, uint16_t queue_id,
 
        vq = dev->virtqueue[queue_id];
 
+       if (unlikely(!rte_spinlock_is_locked(&vq->access_lock))) {
+               VHOST_LOG_DATA(ERR, "(%s) %s() called without access lock taken.\n",
+                               dev->ifname, __func__);
+               return -1;
+       }
+
        if (unlikely(!vq->async)) {
                VHOST_LOG_DATA(ERR, "(%s) %s: async not registered for queue id %d.\n",
                        dev->ifname, __func__, queue_id);