From: Greg Kurz Date: Tue, 24 Jun 2014 17:15:31 +0000 (+0200) Subject: virtio: introduce device specific migration calls X-Git-Tag: v2.1.0-rc0~14^2~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1b5fc0dea469976fcbf6dc2e8f2637a2154af2fb;p=thirdparty%2Fqemu.git virtio: introduce device specific migration calls In order to migrate virtio subsections, they should be streamed after the device itself. We need the device specific code to be called from the common migration code to achieve this. This patch introduces load and save methods for this purpose. Suggested-by: Andreas Färber Signed-off-by: Greg Kurz Reviewed-by: Alexander Graf Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index a222e3f9a4c..5e2693a5685 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -635,7 +635,7 @@ static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id) if (version_id != 2) return -EINVAL; - ret = virtio_load(vdev, f); + ret = virtio_load(vdev, f, version_id); if (ret) { return ret; } diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index e2174b10bb4..f919ec24402 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -670,7 +670,7 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id) } /* The virtio device */ - ret = virtio_load(VIRTIO_DEVICE(s), f); + ret = virtio_load(VIRTIO_DEVICE(s), f, version_id); if (ret) { return ret; } diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index ea1a0819937..acfe91ccb6f 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1362,7 +1362,7 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id) if (version_id < 2 || version_id > VIRTIO_NET_VM_VERSION) return -EINVAL; - ret = virtio_load(vdev, f); + ret = virtio_load(vdev, f, version_id); if (ret) { return ret; } diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 8c8c9d1f61c..6b4fd6f6254 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -549,7 +549,7 @@ static int virtio_scsi_load(QEMUFile *f, void *opaque, int version_id) VirtIODevice *vdev = VIRTIO_DEVICE(opaque); int ret; - ret = virtio_load(vdev, f); + ret = virtio_load(vdev, f, version_id); if (ret) { return ret; } diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 2a2e58a297a..165592e1d7e 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -343,7 +343,7 @@ static int virtio_balloon_load(QEMUFile *f, void *opaque, int version_id) if (version_id != 1) return -EINVAL; - ret = virtio_load(vdev, f); + ret = virtio_load(vdev, f, version_id); if (ret) { return ret; } diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c index b6ab3610cbc..025de813452 100644 --- a/hw/virtio/virtio-rng.c +++ b/hw/virtio/virtio-rng.c @@ -113,7 +113,7 @@ static int virtio_rng_load(QEMUFile *f, void *opaque, int version_id) if (version_id != 1) { return -EINVAL; } - virtio_load(vdev, f); + virtio_load(vdev, f, version_id); /* 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 diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index c1d538c5f3a..7f9ac5e0b9e 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -843,6 +843,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) { BusState *qbus = qdev_get_parent_bus(DEVICE(vdev)); VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); int i; if (k->save_config) { @@ -877,6 +878,10 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) k->save_queue(qbus->parent, i, f); } } + + if (vdc->save != NULL) { + vdc->save(vdev, f); + } } int virtio_set_features(VirtIODevice *vdev, uint32_t val) @@ -895,7 +900,7 @@ int virtio_set_features(VirtIODevice *vdev, uint32_t val) return bad ? -1 : 0; } -int virtio_load(VirtIODevice *vdev, QEMUFile *f) +int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id) { int i, ret; int32_t config_len; @@ -904,6 +909,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f) uint32_t supported_features; BusState *qbus = qdev_get_parent_bus(DEVICE(vdev)); VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); if (k->load_config) { ret = k->load_config(qbus->parent, f); @@ -983,6 +989,11 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f) } virtio_notify_vector(vdev, VIRTIO_NO_VECTOR); + + if (vdc->load != NULL) { + return vdc->load(vdev, f, version_id); + } + return 0; } diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 3e54e90aad6..3505ce511e8 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -150,6 +150,8 @@ typedef struct VirtioDeviceClass { * must mask in frontend instead. */ void (*guest_notifier_mask)(VirtIODevice *vdev, int n, bool mask); + void (*save)(VirtIODevice *vdev, QEMUFile *f); + int (*load)(VirtIODevice *vdev, QEMUFile *f, int version_id); } VirtioDeviceClass; void virtio_init(VirtIODevice *vdev, const char *name, @@ -184,7 +186,7 @@ void virtio_notify(VirtIODevice *vdev, VirtQueue *vq); void virtio_save(VirtIODevice *vdev, QEMUFile *f); -int virtio_load(VirtIODevice *vdev, QEMUFile *f); +int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id); void virtio_notify_config(VirtIODevice *vdev);