From: Pekka Enberg Date: Wed, 5 Jan 2011 16:00:52 +0000 (+0200) Subject: kvm: Implement virtio blk device vring lookup X-Git-Tag: next-20110824~3^2~528^2~34 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=1a89ab75dc760350aacaeffafad24c202652b64d;p=karo-tx-linux.git kvm: Implement virtio blk device vring lookup 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 --- diff --git a/tools/kvm/blk-virtio.c b/tools/kvm/blk-virtio.c index 9f98805761ca..f67457a12436 100644 --- a/tools/kvm/blk-virtio.c +++ b/tools/kvm/blk-virtio.c @@ -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" @@ -14,8 +15,11 @@ #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; }