diff options
Diffstat (limited to 'hw/virtio')
-rw-r--r-- | hw/virtio/virtio-balloon.c | 19 | ||||
-rw-r--r-- | hw/virtio/virtio-pci.c | 10 | ||||
-rw-r--r-- | hw/virtio/virtio-rng.c | 20 | ||||
-rw-r--r-- | hw/virtio/virtio.c | 51 |
4 files changed, 57 insertions, 43 deletions
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 1a22e6d993..5af429a58a 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -396,11 +396,6 @@ static void virtio_balloon_to_target(void *opaque, ram_addr_t target) trace_virtio_balloon_to_target(target, dev->num_pages); } -static void virtio_balloon_save(QEMUFile *f, void *opaque) -{ - virtio_save(VIRTIO_DEVICE(opaque), f); -} - static void virtio_balloon_save_device(VirtIODevice *vdev, QEMUFile *f) { VirtIOBalloon *s = VIRTIO_BALLOON(vdev); @@ -409,12 +404,9 @@ static void virtio_balloon_save_device(VirtIODevice *vdev, QEMUFile *f) qemu_put_be32(f, s->actual); } -static int virtio_balloon_load(QEMUFile *f, void *opaque, int version_id) +static int virtio_balloon_load(QEMUFile *f, void *opaque, size_t size) { - if (version_id != 1) - return -EINVAL; - - return virtio_load(VIRTIO_DEVICE(opaque), f, version_id); + return virtio_load(VIRTIO_DEVICE(opaque), f, 1); } static int virtio_balloon_load_device(VirtIODevice *vdev, QEMUFile *f, @@ -454,9 +446,6 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp) s->svq = virtio_add_queue(vdev, 128, virtio_balloon_receive_stats); reset_stats(s); - - register_savevm(dev, "virtio-balloon", -1, 1, - virtio_balloon_save, virtio_balloon_load, s); } static void virtio_balloon_device_unrealize(DeviceState *dev, Error **errp) @@ -466,7 +455,6 @@ static void virtio_balloon_device_unrealize(DeviceState *dev, Error **errp) balloon_stats_destroy_timer(s); qemu_remove_balloon_handler(s); - unregister_savevm(dev, "virtio-balloon", s); virtio_cleanup(vdev); } @@ -493,6 +481,8 @@ static void virtio_balloon_instance_init(Object *obj) NULL, s, NULL); } +VMSTATE_VIRTIO_DEVICE(balloon, 1, virtio_balloon_load, virtio_vmstate_save); + static Property virtio_balloon_properties[] = { DEFINE_PROP_BIT("deflate-on-oom", VirtIOBalloon, host_features, VIRTIO_BALLOON_F_DEFLATE_ON_OOM, false), @@ -505,6 +495,7 @@ static void virtio_balloon_class_init(ObjectClass *klass, void *data) VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); dc->props = virtio_balloon_properties; + dc->vmsd = &vmstate_virtio_balloon; set_bit(DEVICE_CATEGORY_MISC, dc->categories); vdc->realize = virtio_balloon_device_realize; vdc->unrealize = virtio_balloon_device_unrealize; diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 2b34b43060..f0677b73d8 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -699,14 +699,13 @@ static uint32_t virtio_read_config(PCIDevice *pci_dev, static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy, unsigned int queue_no, - unsigned int vector, - MSIMessage msg) + unsigned int vector) { VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector]; int ret; if (irqfd->users == 0) { - ret = kvm_irqchip_add_msi_route(kvm_state, msg, &proxy->pci_dev); + ret = kvm_irqchip_add_msi_route(kvm_state, vector, &proxy->pci_dev); if (ret < 0) { return ret; } @@ -757,7 +756,6 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); unsigned int vector; int ret, queue_no; - MSIMessage msg; for (queue_no = 0; queue_no < nvqs; queue_no++) { if (!virtio_queue_get_num(vdev, queue_no)) { @@ -767,8 +765,7 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) if (vector >= msix_nr_vectors_allocated(dev)) { continue; } - msg = msix_get_message(dev, vector); - ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector, msg); + ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector); if (ret < 0) { goto undo; } @@ -845,6 +842,7 @@ static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy, if (ret < 0) { return ret; } + kvm_irqchip_commit_routes(kvm_state); } } diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c index 6b991a7642..cd8ca10177 100644 --- a/hw/virtio/virtio-rng.c +++ b/hw/virtio/virtio-rng.c @@ -120,22 +120,12 @@ static uint64_t get_features(VirtIODevice *vdev, uint64_t f, Error **errp) return f; } -static void virtio_rng_save(QEMUFile *f, void *opaque) -{ - VirtIODevice *vdev = opaque; - - virtio_save(vdev, f); -} - -static int virtio_rng_load(QEMUFile *f, void *opaque, int version_id) +static int virtio_rng_load(QEMUFile *f, void *opaque, size_t size) { VirtIORNG *vrng = opaque; int ret; - if (version_id != 1) { - return -EINVAL; - } - ret = virtio_load(VIRTIO_DEVICE(vrng), f, version_id); + ret = virtio_load(VIRTIO_DEVICE(vrng), f, 1); if (ret != 0) { return ret; } @@ -214,8 +204,6 @@ static void virtio_rng_device_realize(DeviceState *dev, Error **errp) vrng->rate_limit_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, check_rate_limit, vrng); vrng->activate_timer = true; - register_savevm(dev, "virtio-rng", -1, 1, virtio_rng_save, - virtio_rng_load, vrng); } static void virtio_rng_device_unrealize(DeviceState *dev, Error **errp) @@ -225,10 +213,11 @@ static void virtio_rng_device_unrealize(DeviceState *dev, Error **errp) timer_del(vrng->rate_limit_timer); timer_free(vrng->rate_limit_timer); - unregister_savevm(dev, "virtio-rng", vrng); virtio_cleanup(vdev); } +VMSTATE_VIRTIO_DEVICE(rng, 1, virtio_rng_load, virtio_vmstate_save); + static Property virtio_rng_properties[] = { /* Set a default rate limit of 2^47 bytes per minute or roughly 2TB/s. If * you have an entropy source capable of generating more entropy than this @@ -246,6 +235,7 @@ static void virtio_rng_class_init(ObjectClass *klass, void *data) VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); dc->props = virtio_rng_properties; + dc->vmsd = &vmstate_virtio_rng; set_bit(DEVICE_CATEGORY_MISC, dc->categories); vdc->realize = virtio_rng_device_realize; vdc->unrealize = virtio_rng_device_unrealize; diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 18153d5a39..752b2715d0 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -95,8 +95,9 @@ struct VirtQueue int inuse; uint16_t vector; - void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq); - void (*handle_aio_output)(VirtIODevice *vdev, VirtQueue *vq); + VirtIOHandleOutput handle_output; + VirtIOHandleOutput handle_aio_output; + bool use_aio; VirtIODevice *vdev; EventNotifier guest_notifier; EventNotifier host_notifier; @@ -1130,8 +1131,9 @@ void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector) } } -VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, - void (*handle_output)(VirtIODevice *, VirtQueue *)) +static VirtQueue *virtio_add_queue_internal(VirtIODevice *vdev, int queue_size, + VirtIOHandleOutput handle_output, + bool use_aio) { int i; @@ -1148,10 +1150,28 @@ VirtQueue *virtio_add_queue(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) { @@ -1444,6 +1464,12 @@ 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); @@ -1804,8 +1830,7 @@ static void virtio_queue_host_notifier_aio_read(EventNotifier *n) } void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx, - void (*handle_output)(VirtIODevice *, - VirtQueue *)) + VirtIOHandleOutput handle_output) { if (handle_output) { vq->handle_aio_output = handle_output; @@ -1831,11 +1856,21 @@ 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) { - event_notifier_set_handler(&vq->host_notifier, true, + if (vq->use_aio) { + aio_set_event_notifier(ctx, &vq->host_notifier, true, virtio_queue_host_notifier_read); + } else { + event_notifier_set_handler(&vq->host_notifier, true, + virtio_queue_host_notifier_read); + } } else { - event_notifier_set_handler(&vq->host_notifier, true, NULL); + if (vq->use_aio) { + aio_set_event_notifier(ctx, &vq->host_notifier, true, NULL); + } else { + event_notifier_set_handler(&vq->host_notifier, true, NULL); + } } if (!assign) { /* Test and clear notifier before after disabling event, |