aboutsummaryrefslogtreecommitdiff
path: root/hw/virtio
diff options
context:
space:
mode:
Diffstat (limited to 'hw/virtio')
-rw-r--r--hw/virtio/virtio-balloon.c19
-rw-r--r--hw/virtio/virtio-pci.c10
-rw-r--r--hw/virtio/virtio-rng.c20
-rw-r--r--hw/virtio/virtio.c51
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,