diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2016-10-10 16:23:40 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2016-10-10 16:23:40 +0100 |
commit | 627eae7d729277c84f8e0ac07a8caab39c92c38d (patch) | |
tree | fe42de6f2cbeb5a5f2ab64f16eff5da7b3993ae9 /hw/virtio | |
parent | 0f183e679d85fec74fc83f35f973cf8e56d97861 (diff) | |
parent | dea651a95af6dad0997b840241a0bf6059d9a776 (diff) |
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
virtio, pc: fixes and features
more guest error handling for virtio devices
virtio migration rework
pc fixes
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
# gpg: Signature made Mon 10 Oct 2016 00:39:11 BST
# gpg: using RSA key 0x281F0DB8D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg: aka "Michael S. Tsirkin <mst@redhat.com>"
# Primary key fingerprint: 0270 606B 6F3C DF3D 0B17 0970 C350 3912 AFBE 8E67
# Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA 8A0D 281F 0DB8 D28D 5469
* remotes/mst/tags/for_upstream: (33 commits)
intel-iommu: Check IOAPIC's Trigger Mode against the one in IRTE
virtio: cleanup VMSTATE_VIRTIO_DEVICE
vhost-vsock: convert VMSTATE_VIRTIO_DEVICE
virtio-rng: convert VMSTATE_VIRTIO_DEVICE
virtio-balloon: convert VMSTATE_VIRTIO_DEVICE
virtio-scsi: convert VMSTATE_VIRTIO_DEVICE
virtio-input: convert VMSTATE_VIRTIO_DEVICE
virtio-gpu: convert VMSTATE_VIRTIO_DEVICE
virtio-serial: convert VMSTATE_VIRTIO_DEVICE
virtio-9p: convert VMSTATE_VIRTIO_DEVICE
virtio-net: convert VMSTATE_VIRTIO_DEVICE
virtio-blk: convert VMSTATE_VIRTIO_DEVICE
virtio: prepare change VMSTATE_VIRTIO_DEVICE macro
net: don't poke at chardev internal QemuOpts
virtio-scsi: handle virtio_scsi_set_config() error
virtio-scsi: convert virtio_scsi_bad_req() to use virtio_error()
virtio-net: handle virtio_net_flush_tx() errors
virtio-net: handle virtio_net_receive() errors
virtio-net: handle virtio_net_handle_ctrl() error
virtio-blk: handle virtio_blk_handle_request() errors
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/virtio')
-rw-r--r-- | hw/virtio/vhost-vsock.c | 42 | ||||
-rw-r--r-- | hw/virtio/virtio-balloon.c | 17 | ||||
-rw-r--r-- | hw/virtio/virtio-rng.c | 19 | ||||
-rw-r--r-- | hw/virtio/virtio.c | 44 |
4 files changed, 82 insertions, 40 deletions
diff --git a/hw/virtio/vhost-vsock.c b/hw/virtio/vhost-vsock.c index bde2456621..b4815629e1 100644 --- a/hw/virtio/vhost-vsock.c +++ b/hw/virtio/vhost-vsock.c @@ -236,17 +236,6 @@ out: g_free(elem); } -static void vhost_vsock_save(QEMUFile *f, void *opaque, size_t size) -{ - VHostVSock *vsock = opaque; - VirtIODevice *vdev = VIRTIO_DEVICE(vsock); - - /* At this point, backend must be stopped, otherwise - * it might keep writing to memory. */ - assert(!vsock->vhost_dev.started); - virtio_save(vdev, f); -} - static void vhost_vsock_post_load_timer_cleanup(VHostVSock *vsock) { if (!vsock->post_load_timer) { @@ -266,16 +255,19 @@ static void vhost_vsock_post_load_timer_cb(void *opaque) vhost_vsock_send_transport_reset(vsock); } -static int vhost_vsock_load(QEMUFile *f, void *opaque, size_t size) +static void vhost_vsock_pre_save(void *opaque) { VHostVSock *vsock = opaque; - VirtIODevice *vdev = VIRTIO_DEVICE(vsock); - int ret; - ret = virtio_load(vdev, f, VHOST_VSOCK_SAVEVM_VERSION); - if (ret) { - return ret; - } + /* At this point, backend must be stopped, otherwise + * it might keep writing to memory. */ + assert(!vsock->vhost_dev.started); +} + +static int vhost_vsock_post_load(void *opaque, int version_id) +{ + VHostVSock *vsock = opaque; + VirtIODevice *vdev = VIRTIO_DEVICE(vsock); if (virtio_queue_get_addr(vdev, 2)) { /* Defer transport reset event to a vm clock timer so that virtqueue @@ -288,12 +280,20 @@ static int vhost_vsock_load(QEMUFile *f, void *opaque, size_t size) vsock); timer_mod(vsock->post_load_timer, 1); } - return 0; } -VMSTATE_VIRTIO_DEVICE(vhost_vsock, VHOST_VSOCK_SAVEVM_VERSION, - vhost_vsock_load, vhost_vsock_save); +static const VMStateDescription vmstate_virtio_vhost_vsock = { + .name = "virtio-vhost_vsock", + .minimum_version_id = VHOST_VSOCK_SAVEVM_VERSION, + .version_id = VHOST_VSOCK_SAVEVM_VERSION, + .fields = (VMStateField[]) { + VMSTATE_VIRTIO_DEVICE, + VMSTATE_END_OF_LIST() + }, + .pre_save = vhost_vsock_pre_save, + .post_load = vhost_vsock_post_load, +}; static void vhost_vsock_device_realize(DeviceState *dev, Error **errp) { diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 49a2f4aade..1d77028236 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -34,13 +34,11 @@ static void balloon_page(void *addr, int deflate) { -#if defined(__linux__) if (!qemu_balloon_is_inhibited() && (!kvm_enabled() || kvm_has_sync_mmu())) { qemu_madvise(addr, BALLOON_PAGE_SIZE, deflate ? QEMU_MADV_WILLNEED : QEMU_MADV_DONTNEED); } -#endif } static const char *balloon_stat_names[] = { @@ -404,11 +402,6 @@ 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, size_t size) -{ - return virtio_load(VIRTIO_DEVICE(opaque), f, 1); -} - static int virtio_balloon_load_device(VirtIODevice *vdev, QEMUFile *f, int version_id) { @@ -494,7 +487,15 @@ static void virtio_balloon_instance_init(Object *obj) NULL, s, NULL); } -VMSTATE_VIRTIO_DEVICE(balloon, 1, virtio_balloon_load, virtio_vmstate_save); +static const VMStateDescription vmstate_virtio_balloon = { + .name = "virtio-balloon", + .minimum_version_id = 1, + .version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_VIRTIO_DEVICE, + VMSTATE_END_OF_LIST() + }, +}; static Property virtio_balloon_properties[] = { DEFINE_PROP_BIT("deflate-on-oom", VirtIOBalloon, host_features, diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c index cd8ca10177..9639f4e89b 100644 --- a/hw/virtio/virtio-rng.c +++ b/hw/virtio/virtio-rng.c @@ -120,15 +120,9 @@ static uint64_t get_features(VirtIODevice *vdev, uint64_t f, Error **errp) return f; } -static int virtio_rng_load(QEMUFile *f, void *opaque, size_t size) +static int virtio_rng_post_load(void *opaque, int version_id) { VirtIORNG *vrng = opaque; - int ret; - - ret = virtio_load(VIRTIO_DEVICE(vrng), f, 1); - if (ret != 0) { - return ret; - } /* We may have an element ready but couldn't process it due to a quota * limit. Make sure to try again after live migration when the quota may @@ -216,7 +210,16 @@ static void virtio_rng_device_unrealize(DeviceState *dev, Error **errp) virtio_cleanup(vdev); } -VMSTATE_VIRTIO_DEVICE(rng, 1, virtio_rng_load, virtio_vmstate_save); +static const VMStateDescription vmstate_virtio_rng = { + .name = "virtio-rng", + .minimum_version_id = 1, + .version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_VIRTIO_DEVICE, + VMSTATE_END_OF_LIST() + }, + .post_load = virtio_rng_post_load, +}; static Property virtio_rng_properties[] = { /* Set a default rate limit of 2^47 bytes per minute or roughly 2TB/s. If diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 18ce333457..d48d1a98a7 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -264,12 +264,35 @@ static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem, 0, elem->out_sg[i].iov_len); } +/* virtqueue_detach_element: + * @vq: The #VirtQueue + * @elem: The #VirtQueueElement + * @len: number of bytes written + * + * Detach the element from the virtqueue. This function is suitable for device + * reset or other situations where a #VirtQueueElement is simply freed and will + * not be pushed or discarded. + */ +void virtqueue_detach_element(VirtQueue *vq, const VirtQueueElement *elem, + unsigned int len) +{ + vq->inuse--; + virtqueue_unmap_sg(vq, elem, len); +} + +/* virtqueue_discard: + * @vq: The #VirtQueue + * @elem: The #VirtQueueElement + * @len: number of bytes written + * + * Pretend the most recent element wasn't popped from the virtqueue. The next + * call to virtqueue_pop() will refetch the element. + */ void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem, unsigned int len) { vq->last_avail_idx--; - vq->inuse--; - virtqueue_unmap_sg(vq, elem, len); + virtqueue_detach_element(vq, elem, len); } /* virtqueue_rewind: @@ -1617,11 +1640,26 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) } /* A wrapper for use as a VMState .put function */ -void virtio_vmstate_save(QEMUFile *f, void *opaque, size_t size) +static void virtio_device_put(QEMUFile *f, void *opaque, size_t size) { virtio_save(VIRTIO_DEVICE(opaque), f); } +/* A wrapper for use as a VMState .get function */ +static int virtio_device_get(QEMUFile *f, void *opaque, size_t size) +{ + VirtIODevice *vdev = VIRTIO_DEVICE(opaque); + DeviceClass *dc = DEVICE_CLASS(VIRTIO_DEVICE_GET_CLASS(vdev)); + + return virtio_load(vdev, f, dc->vmsd->version_id); +} + +const VMStateInfo virtio_vmstate_info = { + .name = "virtio", + .get = virtio_device_get, + .put = virtio_device_put, +}; + static int virtio_set_features_nocheck(VirtIODevice *vdev, uint64_t val) { VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); |