1 #include <linux/virtio_ring.h>
2 #include <linux/types.h>
5 #include "kvm/barrier.h"
8 #include "kvm/virtio.h"
10 struct vring_used_elem
*virt_queue__set_used_elem(struct virt_queue
*queue
, u32 head
, u32 len
)
12 struct vring_used_elem
*used_elem
;
14 used_elem
= &queue
->vring
.used
->ring
[queue
->vring
.used
->idx
% queue
->vring
.num
];
19 * Use wmb to assure that used elem was updated with head and len.
20 * We need a wmb here since we can't advance idx unless we're ready
21 * to pass the used element to the guest.
24 queue
->vring
.used
->idx
++;
27 * Use wmb to assure used idx has been increased before we signal the guest.
28 * Without a wmb here the guest may ignore the queue since it won't see
36 u16
virt_queue__get_iov(struct virt_queue
*queue
, struct iovec iov
[], u16
*out
, u16
*in
, struct kvm
*kvm
)
38 struct vring_desc
*desc
;
41 idx
= head
= virt_queue__pop(queue
);
45 desc
= virt_queue__get_desc(queue
, idx
);
46 iov
[*out
+ *in
].iov_base
= guest_flat_to_host(kvm
, desc
->addr
);
47 iov
[*out
+ *in
].iov_len
= desc
->len
;
48 if (desc
->flags
& VRING_DESC_F_WRITE
)
52 if (desc
->flags
& VRING_DESC_F_NEXT
)
61 /* in and out are relative to guest */
62 u16
virt_queue__get_inout_iov(struct kvm
*kvm
, struct virt_queue
*queue
,
63 struct iovec in_iov
[], struct iovec out_iov
[],
67 struct vring_desc
*desc
;
69 idx
= head
= virt_queue__pop(queue
);
72 desc
= virt_queue__get_desc(queue
, idx
);
73 if (desc
->flags
& VRING_DESC_F_WRITE
) {
74 in_iov
[*in
].iov_base
= guest_flat_to_host(kvm
,
76 in_iov
[*in
].iov_len
= desc
->len
;
79 out_iov
[*out
].iov_base
= guest_flat_to_host(kvm
,
81 out_iov
[*out
].iov_len
= desc
->len
;
84 if (desc
->flags
& VRING_DESC_F_NEXT
)
93 void virt_queue__trigger_irq(struct virt_queue
*vq
, int irq
, u8
*isr
, struct kvm
*kvm
)
95 if (vq
->vring
.avail
->flags
& VRING_AVAIL_F_NO_INTERRUPT
)
98 if (*isr
== VIRTIO_IRQ_LOW
) {
99 *isr
= VIRTIO_IRQ_HIGH
;
100 kvm__irq_line(kvm
, irq
, VIRTIO_IRQ_HIGH
);
104 int virtio__get_dev_specific_field(int offset
, bool msix
, bool features_hi
, u32
*config_off
)
108 return VIRTIO_PCI_O_MSIX
;
115 return VIRTIO_PCI_O_FEATURES
;
120 *config_off
= offset
;
122 return VIRTIO_PCI_O_CONFIG
;