From 361b460f56371bd44539b6f1712b6122810996e1 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Sat, 8 Jan 2011 12:18:44 +0200 Subject: [PATCH] kvm: Fix virtqueue ring index check This patch fixes the virtqueu ring index check that was totally wrong. The ->last_avail_idx is the index we've last seen but it doesn't need to match with avail->idx. Signed-off-by: Pekka Enberg --- tools/kvm/blk-virtio.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tools/kvm/blk-virtio.c b/tools/kvm/blk-virtio.c index 7887dbe323e0..a99738e2d388 100644 --- a/tools/kvm/blk-virtio.c +++ b/tools/kvm/blk-virtio.c @@ -18,9 +18,9 @@ struct virt_queue { struct vring vring; uint32_t pfn; - /* The next_avail_ndx field is an index to ->ring of struct vring_avail. + /* The last_avail_idx field is an index to ->ring of struct vring_avail. It's where we assume the next request index is at. */ - uint16_t next_avail_ndx; + uint16_t last_avail_idx; }; struct device { @@ -152,13 +152,15 @@ static bool blk_virtio_out(struct kvm *self, uint16_t port, void *data, int size queue = &device.virt_queues[queue_index]; - desc_ndx = queue->vring.avail->ring[queue->next_avail_ndx++ % queue->vring.num]; + if (queue->vring.avail->idx == queue->last_avail_idx) { + warning("vring is empty"); + break; + } + + desc_ndx = queue->vring.avail->ring[queue->last_avail_idx++ % queue->vring.num]; - if (queue->vring.avail->idx != queue->next_avail_ndx) { - /* - * The hypervisor and the guest disagree on next index. - */ - warning("I/O error"); + if (desc_ndx >= queue->vring.num) { + warning("fatal I/O error"); break; } -- 2.39.5