]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
kvm: Implement virtio blk device vring lookup
authorPekka Enberg <penberg@kernel.org>
Wed, 5 Jan 2011 16:00:52 +0000 (18:00 +0200)
committerPekka Enberg <penberg@kernel.org>
Wed, 5 Jan 2011 16:10:10 +0000 (18:10 +0200)
This patch changes VIRTIO_PCI_QUEUE_NOTIFY handler to look up the actual I/O
request from the vring. We don't inject anything back to the guest yet.

Signed-off-by: Pekka Enberg <penberg@kernel.org>
tools/kvm/blk-virtio.c

index 9f98805761ca46d47150cc9ff55cc7de697e154e..f67457a12436a03fc71ce8f905ceac28dda48acf 100644 (file)
@@ -4,6 +4,7 @@
 #include "kvm/virtio_blk.h"
 #include "kvm/virtio_pci.h"
 #include "kvm/ioport.h"
+#include "kvm/util.h"
 #include "kvm/kvm.h"
 #include "kvm/pci.h"
 
 #define VIRTIO_BLK_QUEUE_SIZE  16
 
 struct virt_queue {
-       uint32_t                        pfn;
        struct vring                    vring;
+       uint32_t                        pfn;
+       /* The next_avail_ndx 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;
 };
 
 struct device {
@@ -130,13 +134,30 @@ static bool blk_virtio_out(struct kvm *self, uint16_t port, void *data, int size
                device.queue_selector   = ioport__read16(data);
                break;
        case VIRTIO_PCI_QUEUE_NOTIFY: {
+               struct virtio_blk_outhdr *req;
                struct virt_queue *queue;
+               struct vring_desc *desc;
                uint16_t queue_index;
+               uint16_t desc_ndx;
 
                queue_index             = ioport__read16(data);
 
                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->next_avail_ndx) {
+                       /*
+                        * The hypervisor and the guest disagree on next index.
+                        */
+                       warning("I/O error");
+                       break;
+               }
+
+               desc                    = &queue->vring.desc[desc_ndx];
+
+               req                     = guest_flat_to_host(self, desc->addr);
+
                kvm__irq_line(self, VIRTIO_BLK_IRQ, 1);
                break;
        }