1 #include <linux/virtio_ring.h> 2 #include <stdint.h> 3 #include <sys/uio.h> 4 #include "kvm/kvm.h" 5 #include "kvm/virtio.h" 6 7 struct vring_used_elem *virt_queue__set_used_elem(struct virt_queue *queue, uint32_t head, uint32_t len) 8 { 9 struct vring_used_elem *used_elem; 10 used_elem = &queue->vring.used->ring[queue->vring.used->idx++ % queue->vring.num]; 11 used_elem->id = head; 12 used_elem->len = len; 13 return used_elem; 14 } 15 16 uint16_t virt_queue__get_iov(struct virt_queue *queue, struct iovec iov[], uint16_t *out, uint16_t *in, struct kvm *kvm) 17 { 18 struct vring_desc *desc; 19 uint16_t head, idx; 20 21 idx = head = virt_queue__pop(queue); 22 *out = *in = 0; 23 24 do { 25 desc = virt_queue__get_desc(queue, idx); 26 iov[*out + *in].iov_base = guest_flat_to_host(kvm, desc->addr); 27 iov[*out + *in].iov_len = desc->len; 28 if (desc->flags & VRING_DESC_F_WRITE) 29 (*in)++; 30 else 31 (*out)++; 32 if (desc->flags & VRING_DESC_F_NEXT) 33 idx = desc->next; 34 else 35 break; 36 } while (1); 37 38 return head; 39 } 40