summaryrefslogtreecommitdiffstats
path: root/hw/s390x/virtio-ccw.c
diff options
context:
space:
mode:
authorHalil Pasic2017-07-03 23:34:14 +0200
committerChristian Borntraeger2017-07-05 12:16:55 +0200
commit517ff12c7d000fa1f5b1e989b22fb86a286f9cc2 (patch)
treeaa90c178a043677efea46bbcbd61028295a49c7e /hw/s390x/virtio-ccw.c
parentMerge remote-tracking branch 'remotes/edgar/tags/edgar/xilinx-next.for-upstre... (diff)
downloadqemu-517ff12c7d000fa1f5b1e989b22fb86a286f9cc2.tar.gz
qemu-517ff12c7d000fa1f5b1e989b22fb86a286f9cc2.tar.xz
qemu-517ff12c7d000fa1f5b1e989b22fb86a286f9cc2.zip
s390x: vmstatify config migration for virtio-ccw
Let's vmstatify virtio_ccw_save_config and virtio_ccw_load_config for flexibility (extending using subsections) and for fun. To achieve this we need to hack the config_vector, which is VirtIODevice (that is common virtio) state, in the middle of the VirtioCcwDevice state representation. This is somewhat ugly, but we have no choice because the stream format needs to be preserved. Almost no changes in behavior. Exception is everything that comes with vmstate like extra bookkeeping about what's in the stream, and maybe some extra checks and better error reporting. Signed-off-by: Halil Pasic <pasic@linux.vnet.ibm.com> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Reviewed-by: Juan Quintela <quintela@redhat.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Message-Id: <20170703213414.94298-1-pasic@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'hw/s390x/virtio-ccw.c')
-rw-r--r--hw/s390x/virtio-ccw.c158
1 files changed, 80 insertions, 78 deletions
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 90d37cb9ff..f0e7fc8e9b 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -34,9 +34,87 @@
#include "virtio-ccw.h"
#include "trace.h"
#include "hw/s390x/css-bridge.h"
+#include "hw/s390x/s390-virtio-ccw.h"
#define NR_CLASSIC_INDICATOR_BITS 64
+static int virtio_ccw_dev_post_load(void *opaque, int version_id)
+{
+ VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(opaque);
+ CcwDevice *ccw_dev = CCW_DEVICE(dev);
+ CCWDeviceClass *ck = CCW_DEVICE_GET_CLASS(ccw_dev);
+
+ ccw_dev->sch->driver_data = dev;
+ if (ccw_dev->sch->thinint_active) {
+ dev->routes.adapter.adapter_id = css_get_adapter_id(
+ CSS_IO_ADAPTER_VIRTIO,
+ dev->thinint_isc);
+ }
+ /* Re-fill subch_id after loading the subchannel states.*/
+ if (ck->refill_ids) {
+ ck->refill_ids(ccw_dev);
+ }
+ return 0;
+}
+
+typedef struct VirtioCcwDeviceTmp {
+ VirtioCcwDevice *parent;
+ uint16_t config_vector;
+} VirtioCcwDeviceTmp;
+
+static void virtio_ccw_dev_tmp_pre_save(void *opaque)
+{
+ VirtioCcwDeviceTmp *tmp = opaque;
+ VirtioCcwDevice *dev = tmp->parent;
+ VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
+
+ tmp->config_vector = vdev->config_vector;
+}
+
+static int virtio_ccw_dev_tmp_post_load(void *opaque, int version_id)
+{
+ VirtioCcwDeviceTmp *tmp = opaque;
+ VirtioCcwDevice *dev = tmp->parent;
+ VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
+
+ vdev->config_vector = tmp->config_vector;
+ return 0;
+}
+
+const VMStateDescription vmstate_virtio_ccw_dev_tmp = {
+ .name = "s390_virtio_ccw_dev_tmp",
+ .pre_save = virtio_ccw_dev_tmp_pre_save,
+ .post_load = virtio_ccw_dev_tmp_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT16(config_vector, VirtioCcwDeviceTmp),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+const VMStateDescription vmstate_virtio_ccw_dev = {
+ .name = "s390_virtio_ccw_dev",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .post_load = virtio_ccw_dev_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_CCW_DEVICE(parent_obj, VirtioCcwDevice),
+ VMSTATE_PTR_TO_IND_ADDR(indicators, VirtioCcwDevice),
+ VMSTATE_PTR_TO_IND_ADDR(indicators2, VirtioCcwDevice),
+ VMSTATE_PTR_TO_IND_ADDR(summary_indicator, VirtioCcwDevice),
+ /*
+ * Ugly hack because VirtIODevice does not migrate itself.
+ * This also makes legacy via vmstate_save_state possible.
+ */
+ VMSTATE_WITH_TMP(VirtioCcwDevice, VirtioCcwDeviceTmp,
+ vmstate_virtio_ccw_dev_tmp),
+ VMSTATE_STRUCT(routes, VirtioCcwDevice, 1, vmstate_adapter_routes,
+ AdapterRoutes),
+ VMSTATE_UINT8(thinint_isc, VirtioCcwDevice),
+ VMSTATE_INT32(revision, VirtioCcwDevice),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static void virtio_ccw_bus_new(VirtioBusState *bus, size_t bus_size,
VirtioCcwDevice *dev);
@@ -1239,89 +1317,13 @@ static int virtio_ccw_load_queue(DeviceState *d, int n, QEMUFile *f)
static void virtio_ccw_save_config(DeviceState *d, QEMUFile *f)
{
VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
- CcwDevice *ccw_dev = CCW_DEVICE(d);
- SubchDev *s = ccw_dev->sch;
- VirtIODevice *vdev = virtio_ccw_get_vdev(s);
-
- subch_device_save(s, f);
- if (dev->indicators != NULL) {
- qemu_put_be32(f, dev->indicators->len);
- qemu_put_be64(f, dev->indicators->addr);
- } else {
- qemu_put_be32(f, 0);
- qemu_put_be64(f, 0UL);
- }
- if (dev->indicators2 != NULL) {
- qemu_put_be32(f, dev->indicators2->len);
- qemu_put_be64(f, dev->indicators2->addr);
- } else {
- qemu_put_be32(f, 0);
- qemu_put_be64(f, 0UL);
- }
- if (dev->summary_indicator != NULL) {
- qemu_put_be32(f, dev->summary_indicator->len);
- qemu_put_be64(f, dev->summary_indicator->addr);
- } else {
- qemu_put_be32(f, 0);
- qemu_put_be64(f, 0UL);
- }
- qemu_put_be16(f, vdev->config_vector);
- qemu_put_be64(f, dev->routes.adapter.ind_offset);
- qemu_put_byte(f, dev->thinint_isc);
- qemu_put_be32(f, dev->revision);
+ vmstate_save_state(f, &vmstate_virtio_ccw_dev, dev, NULL);
}
static int virtio_ccw_load_config(DeviceState *d, QEMUFile *f)
{
VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
- CcwDevice *ccw_dev = CCW_DEVICE(d);
- CCWDeviceClass *ck = CCW_DEVICE_GET_CLASS(ccw_dev);
- SubchDev *s = ccw_dev->sch;
- VirtIODevice *vdev = virtio_ccw_get_vdev(s);
- int len;
- int ret;
-
- s->driver_data = dev;
- ret = subch_device_load(s, f);
- if (ret) {
- return ret;
- }
- /* Re-fill subch_id after loading the subchannel states.*/
- if (ck->refill_ids) {
- ck->refill_ids(ccw_dev);
- }
- len = qemu_get_be32(f);
- if (len != 0) {
- dev->indicators = get_indicator(qemu_get_be64(f), len);
- } else {
- qemu_get_be64(f);
- dev->indicators = NULL;
- }
- len = qemu_get_be32(f);
- if (len != 0) {
- dev->indicators2 = get_indicator(qemu_get_be64(f), len);
- } else {
- qemu_get_be64(f);
- dev->indicators2 = NULL;
- }
- len = qemu_get_be32(f);
- if (len != 0) {
- dev->summary_indicator = get_indicator(qemu_get_be64(f), len);
- } else {
- qemu_get_be64(f);
- dev->summary_indicator = NULL;
- }
- qemu_get_be16s(f, &vdev->config_vector);
- dev->routes.adapter.ind_offset = qemu_get_be64(f);
- dev->thinint_isc = qemu_get_byte(f);
- dev->revision = qemu_get_be32(f);
- if (s->thinint_active) {
- dev->routes.adapter.adapter_id = css_get_adapter_id(
- CSS_IO_ADAPTER_VIRTIO,
- dev->thinint_isc);
- }
-
- return 0;
+ return vmstate_load_state(f, &vmstate_virtio_ccw_dev, dev, 1);
}
static void virtio_ccw_pre_plugged(DeviceState *d, Error **errp)