From: Maxime Coquelin Date: Wed, 11 May 2022 06:58:37 +0000 (+0200) Subject: vhost: add runtime locking check in unsafe API X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=0a8363efdbeb92446d0fc1f11788a76f8b969daf;p=dpdk.git vhost: add runtime locking check in unsafe API 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 Reviewed-by: David Marchand Reviewed-by: Jiayu Hu Reviewed-by: Chenbo Xia --- diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c index 3537680107..b14521e4d1 100644 --- a/lib/vhost/vhost.c +++ b/lib/vhost/vhost.c @@ -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; diff --git a/lib/vhost/virtio_net.c b/lib/vhost/virtio_net.c index c8905c770a..4961d39007 100644 --- a/lib/vhost/virtio_net.c +++ b/lib/vhost/virtio_net.c @@ -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);