From 808a2b05c2cf1476e55d5659e0cde561c6ab468a Mon Sep 17 00:00:00 2001 From: Dariusz Stojaczyk Date: Sun, 28 Jan 2018 10:53:03 +0100 Subject: [PATCH] vhost: fix overflow of avail entries count Virtio 1.0 says that the effective capacity of vrings is equal to the virtqueue size. When avail ring was full, we detected it as empty. Change-Id: I72f5d45cdc14db6b934ce7780e603a3de3131594 Signed-off-by: Dariusz Stojaczyk Reviewed-on: https://review.gerrithub.io/396804 Tested-by: SPDK Automated Test System Reviewed-by: Pawel Wodkowski Reviewed-by: Daniel Verkamp Reviewed-by: Ben Walker --- lib/vhost/vhost.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c index 11df11001..6cf459126 100644 --- a/lib/vhost/vhost.c +++ b/lib/vhost/vhost.c @@ -102,13 +102,21 @@ spdk_vhost_vq_avail_ring_get(struct spdk_vhost_virtqueue *virtqueue, uint16_t *r struct vring_avail *avail = vring->avail; uint16_t size_mask = vring->size - 1; uint16_t last_idx = vring->last_avail_idx, avail_idx = avail->idx; - uint16_t count = RTE_MIN((avail_idx - last_idx) & size_mask, reqs_len); - uint16_t i; + uint16_t count, i; + count = avail_idx - last_idx; if (spdk_likely(count == 0)) { return 0; } + if (spdk_unlikely(count > vring->size)) { + /* TODO: the queue is unrecoverably broken and should be marked so. + * For now we will fail silently and report there are no new avail entries. + */ + return 0; + } + + count = spdk_min(count, reqs_len); vring->last_avail_idx += count; for (i = 0; i < count; i++) { reqs[i] = vring->avail->ring[(last_idx + i) & size_mask];