summaryrefslogtreecommitdiff
path: root/hw/virtio/virtio.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/virtio/virtio.c')
-rw-r--r--hw/virtio/virtio.c79
1 files changed, 15 insertions, 64 deletions
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 74c085c74..8ed260a61 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -95,9 +95,8 @@ struct VirtQueue
int inuse;
uint16_t vector;
- VirtIOHandleOutput handle_output;
- VirtIOHandleOutput handle_aio_output;
- bool use_aio;
+ void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
+ void (*handle_aio_output)(VirtIODevice *vdev, VirtQueue *vq);
VirtIODevice *vdev;
EventNotifier guest_notifier;
EventNotifier host_notifier;
@@ -268,7 +267,6 @@ void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem,
unsigned int len)
{
vq->last_avail_idx--;
- vq->inuse--;
virtqueue_unmap_sg(vq, elem, len);
}
@@ -459,11 +457,6 @@ static void virtqueue_map_desc(unsigned int *p_num_sg, hwaddr *addr, struct iove
unsigned num_sg = *p_num_sg;
assert(num_sg <= max_num_sg);
- if (!sz) {
- error_report("virtio: zero sized buffers are not allowed");
- exit(1);
- }
-
while (sz) {
hwaddr len = sz;
@@ -1074,6 +1067,13 @@ int virtio_get_num_queues(VirtIODevice *vdev)
return i;
}
+int virtio_queue_get_id(VirtQueue *vq)
+{
+ VirtIODevice *vdev = vq->vdev;
+ assert(vq >= &vdev->vq[0] && vq < &vdev->vq[VIRTIO_QUEUE_MAX]);
+ return vq - &vdev->vq[0];
+}
+
void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
{
BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
@@ -1142,9 +1142,8 @@ void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector)
}
}
-static VirtQueue *virtio_add_queue_internal(VirtIODevice *vdev, int queue_size,
- VirtIOHandleOutput handle_output,
- bool use_aio)
+VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
+ void (*handle_output)(VirtIODevice *, VirtQueue *))
{
int i;
@@ -1161,28 +1160,10 @@ static VirtQueue *virtio_add_queue_internal(VirtIODevice *vdev, int queue_size,
vdev->vq[i].vring.align = VIRTIO_PCI_VRING_ALIGN;
vdev->vq[i].handle_output = handle_output;
vdev->vq[i].handle_aio_output = NULL;
- vdev->vq[i].use_aio = use_aio;
return &vdev->vq[i];
}
-/* Add a virt queue and mark AIO.
- * An AIO queue will use the AioContext based event interface instead of the
- * default IOHandler and EventNotifier interface.
- */
-VirtQueue *virtio_add_queue_aio(VirtIODevice *vdev, int queue_size,
- VirtIOHandleOutput handle_output)
-{
- return virtio_add_queue_internal(vdev, queue_size, handle_output, true);
-}
-
-/* Add a normal virt queue (on the contrary to the AIO version above. */
-VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
- VirtIOHandleOutput handle_output)
-{
- return virtio_add_queue_internal(vdev, queue_size, handle_output, false);
-}
-
void virtio_del_queue(VirtIODevice *vdev, int n)
{
if (n < 0 || n >= VIRTIO_QUEUE_MAX) {
@@ -1475,12 +1456,6 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
vmstate_save_state(f, &vmstate_virtio, vdev, NULL);
}
-/* A wrapper for use as a VMState .put function */
-void virtio_vmstate_save(QEMUFile *f, void *opaque, size_t size)
-{
- virtio_save(VIRTIO_DEVICE(opaque), f);
-}
-
static int virtio_set_features_nocheck(VirtIODevice *vdev, uint64_t val)
{
VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
@@ -1649,21 +1624,6 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
}
vdev->vq[i].used_idx = vring_used_idx(&vdev->vq[i]);
vdev->vq[i].shadow_avail_idx = vring_avail_idx(&vdev->vq[i]);
-
- /*
- * Some devices migrate VirtQueueElements that have been popped
- * from the avail ring but not yet returned to the used ring.
- */
- vdev->vq[i].inuse = vdev->vq[i].last_avail_idx -
- vdev->vq[i].used_idx;
- if (vdev->vq[i].inuse > vdev->vq[i].vring.num) {
- error_report("VQ %d size 0x%x < last_avail_idx 0x%x - "
- "used_idx 0x%x",
- i, vdev->vq[i].vring.num,
- vdev->vq[i].last_avail_idx,
- vdev->vq[i].used_idx);
- return -1;
- }
}
}
@@ -1856,7 +1816,8 @@ static void virtio_queue_host_notifier_aio_read(EventNotifier *n)
}
void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
- VirtIOHandleOutput handle_output)
+ void (*handle_output)(VirtIODevice *,
+ VirtQueue *))
{
if (handle_output) {
vq->handle_aio_output = handle_output;
@@ -1882,21 +1843,11 @@ static void virtio_queue_host_notifier_read(EventNotifier *n)
void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign,
bool set_handler)
{
- AioContext *ctx = qemu_get_aio_context();
if (assign && set_handler) {
- if (vq->use_aio) {
- aio_set_event_notifier(ctx, &vq->host_notifier, true,
+ event_notifier_set_handler(&vq->host_notifier, true,
virtio_queue_host_notifier_read);
- } else {
- event_notifier_set_handler(&vq->host_notifier, true,
- virtio_queue_host_notifier_read);
- }
} else {
- if (vq->use_aio) {
- aio_set_event_notifier(ctx, &vq->host_notifier, true, NULL);
- } else {
- event_notifier_set_handler(&vq->host_notifier, true, NULL);
- }
+ event_notifier_set_handler(&vq->host_notifier, true, NULL);
}
if (!assign) {
/* Test and clear notifier before after disabling event,