]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
kvm tools: Fix virt_queue__set_used_elem
authorSasha Levin <levinsasha928@gmail.com>
Tue, 3 May 2011 20:28:07 +0000 (23:28 +0300)
committerPekka Enberg <penberg@kernel.org>
Wed, 4 May 2011 17:56:48 +0000 (20:56 +0300)
Increase idx only after updating the used element.
Not doing so may mark a buffer as used without having
it's head and length updated.

Acked-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
tools/kvm/virtio.c

index 6249521ea5b14b01968c0c819e857dfe0d9cc856..266a1b6be7efde2ed97825c7f5018f6838ce8981 100644 (file)
@@ -1,15 +1,32 @@
 #include <linux/virtio_ring.h>
 #include <stdint.h>
 #include <sys/uio.h>
+#include <asm/system.h>
 #include "kvm/kvm.h"
 #include "kvm/virtio.h"
 
 struct vring_used_elem *virt_queue__set_used_elem(struct virt_queue *queue, uint32_t head, uint32_t len)
 {
        struct vring_used_elem *used_elem;
-       used_elem       = &queue->vring.used->ring[queue->vring.used->idx++ % queue->vring.num];
+       used_elem       = &queue->vring.used->ring[queue->vring.used->idx % queue->vring.num];
        used_elem->id   = head;
        used_elem->len  = len;
+
+       /*
+        * Use wmb to assure that used elem was updated with head and len.
+        * We need a wmb here since we can't advance idx unless we're ready
+        * to pass the used element to the guest.
+        */
+       wmb();
+       queue->vring.used->idx++;
+
+       /*
+        * Use wmb to assure used idx has been increased before we signal the guest.
+        * Without a wmb here the guest may ignore the queue since it won't see
+        * an updated idx.
+        */
+       wmb();
+
        return used_elem;
 }