Signed-off-by: Eugenio Pérez <eperezma@xxxxxxxxxx> --- include/hw/virtio/virtio.h | 2 ++ hw/virtio/virtio.c | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index b9b8497ea0..0a7f5cc63e 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -233,6 +233,8 @@ int virtio_queue_ready(VirtQueue *vq); int virtio_queue_empty(VirtQueue *vq); +bool virtio_queue_full(const VirtQueue *vq); + /* Host binding interface. */ uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr); diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 3469946538..77ca5f6b6f 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -684,6 +684,17 @@ int virtio_queue_empty(VirtQueue *vq) } } +static bool virtio_queue_full_rcu(const VirtQueue *vq) +{ + return vq->inuse >= vq->vring.num; +} + +bool virtio_queue_full(const VirtQueue *vq) +{ + RCU_READ_LOCK_GUARD(); + return virtio_queue_full_rcu(vq); +} + static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem, unsigned int len) { @@ -1453,7 +1464,7 @@ static void *virtqueue_split_pop(VirtQueue *vq, size_t sz) max = vq->vring.num; - if (vq->inuse >= vq->vring.num) { + if (unlikely(virtio_queue_full_rcu(vq))) { virtio_error(vdev, "Virtqueue size exceeded"); goto done; } @@ -1588,7 +1599,7 @@ static void *virtqueue_packed_pop(VirtQueue *vq, size_t sz) max = vq->vring.num; - if (vq->inuse >= vq->vring.num) { + if (unlikely(virtio_queue_full_rcu(vq))) { virtio_error(vdev, "Virtqueue size exceeded"); goto done; } -- 2.18.4