]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
kvm: Fix virtqueue ring index check
authorPekka Enberg <penberg@kernel.org>
Sat, 8 Jan 2011 10:18:44 +0000 (12:18 +0200)
committerPekka Enberg <penberg@kernel.org>
Sat, 8 Jan 2011 10:26:43 +0000 (12:26 +0200)
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 <penberg@kernel.org>
tools/kvm/blk-virtio.c

index 7887dbe323e010a160a656ded60d55321a39bb29..a99738e2d388344c9f68ad5d685f38396e5ceaec 100644 (file)
@@ -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;
                }