diff options
Diffstat (limited to 'hw/virtio/virtio.c')
-rw-r--r-- | hw/virtio/virtio.c | 79 |
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, |