aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYi Min Zhao <zyimin@linux.vnet.ibm.com>2017-05-16 18:58:44 +0800
committerChristian Borntraeger <borntraeger@de.ibm.com>2017-07-14 12:29:49 +0200
commite7be8d499700f1ebdbfe8094aa19237998c0e1e3 (patch)
treee5f5cb563487c0edc616ff4fcd5e8d8bf82bc9a3
parent3b00f702c236900cca403bdcbed48d59bfec0fba (diff)
s390x/flic: migrate ais states
During migration we should transfer ais states to the target guest. This patch introduces a subsection to kvm_s390_flic_vmstate and new vmsd for qemu_flic. The ais states need to be migrated only when ais is supported. Signed-off-by: Yi Min Zhao <zyimin@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> Reviewed-by: Cornelia Huck <cohuck@redhat.com>
-rw-r--r--hw/intc/s390_flic.c20
-rw-r--r--hw/intc/s390_flic_kvm.c81
-rw-r--r--include/hw/s390x/s390_flic.h1
3 files changed, 102 insertions, 0 deletions
diff --git a/hw/intc/s390_flic.c b/hw/intc/s390_flic.c
index 6e7c610e52..6eaf178d79 100644
--- a/hw/intc/s390_flic.c
+++ b/hw/intc/s390_flic.c
@@ -134,12 +134,32 @@ static void qemu_s390_flic_reset(DeviceState *dev)
flic->nimm = 0;
}
+bool ais_needed(void *opaque)
+{
+ S390FLICState *s = opaque;
+
+ return s->ais_supported;
+}
+
+static const VMStateDescription qemu_s390_flic_vmstate = {
+ .name = "qemu-s390-flic",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = ais_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8(simm, QEMUS390FLICState),
+ VMSTATE_UINT8(nimm, QEMUS390FLICState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static void qemu_s390_flic_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
S390FLICStateClass *fsc = S390_FLIC_COMMON_CLASS(oc);
dc->reset = qemu_s390_flic_reset;
+ dc->vmsd = &qemu_s390_flic_vmstate;
fsc->register_io_adapter = qemu_s390_register_io_adapter;
fsc->io_adapter_map = qemu_s390_io_adapter_map;
fsc->add_adapter_routes = qemu_s390_add_adapter_routes;
diff --git a/hw/intc/s390_flic_kvm.c b/hw/intc/s390_flic_kvm.c
index d93503fcba..be3fd00a57 100644
--- a/hw/intc/s390_flic_kvm.c
+++ b/hw/intc/s390_flic_kvm.c
@@ -413,7 +413,84 @@ out:
return r;
}
+typedef struct KVMS390FLICStateMigTmp {
+ KVMS390FLICState *parent;
+ uint8_t simm;
+ uint8_t nimm;
+} KVMS390FLICStateMigTmp;
+
+static void kvm_flic_ais_pre_save(void *opaque)
+{
+ KVMS390FLICStateMigTmp *tmp = opaque;
+ KVMS390FLICState *flic = tmp->parent;
+ struct kvm_s390_ais_all ais;
+ struct kvm_device_attr attr = {
+ .group = KVM_DEV_FLIC_AISM_ALL,
+ .addr = (uint64_t)&ais,
+ .attr = sizeof(ais),
+ };
+
+ if (ioctl(flic->fd, KVM_GET_DEVICE_ATTR, &attr)) {
+ error_report("Failed to retrieve kvm flic ais states");
+ return;
+ }
+
+ tmp->simm = ais.simm;
+ tmp->nimm = ais.nimm;
+}
+
+static int kvm_flic_ais_post_load(void *opaque, int version_id)
+{
+ KVMS390FLICStateMigTmp *tmp = opaque;
+ KVMS390FLICState *flic = tmp->parent;
+ struct kvm_s390_ais_all ais = {
+ .simm = tmp->simm,
+ .nimm = tmp->nimm,
+ };
+ struct kvm_device_attr attr = {
+ .group = KVM_DEV_FLIC_AISM_ALL,
+ .addr = (uint64_t)&ais,
+ };
+
+ /* This can happen when the user mis-configures its guests in an
+ * incompatible fashion or without a CPU model. For example using
+ * qemu with -cpu host (which is not migration safe) and do a
+ * migration from a host that has AIS to a host that has no AIS.
+ * In that case the target system will reject the migration here.
+ */
+ if (!ais_needed(flic)) {
+ return -ENOSYS;
+ }
+
+ return ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr) ? -errno : 0;
+}
+
+static const VMStateDescription kvm_s390_flic_ais_tmp = {
+ .name = "s390-flic-ais-tmp",
+ .pre_save = kvm_flic_ais_pre_save,
+ .post_load = kvm_flic_ais_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8(simm, KVMS390FLICStateMigTmp),
+ VMSTATE_UINT8(nimm, KVMS390FLICStateMigTmp),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static const VMStateDescription kvm_s390_flic_vmstate_ais = {
+ .name = "s390-flic/ais",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = ais_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_WITH_TMP(KVMS390FLICState, KVMS390FLICStateMigTmp,
+ kvm_s390_flic_ais_tmp),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static const VMStateDescription kvm_s390_flic_vmstate = {
+ /* should have been like kvm-s390-flic,
+ * can't change without breaking compat */
.name = "s390-flic",
.version_id = FLIC_SAVEVM_VERSION,
.minimum_version_id = FLIC_SAVEVM_VERSION,
@@ -428,6 +505,10 @@ static const VMStateDescription kvm_s390_flic_vmstate = {
.flags = VMS_SINGLE,
},
VMSTATE_END_OF_LIST()
+ },
+ .subsections = (const VMStateDescription * []) {
+ &kvm_s390_flic_vmstate_ais,
+ NULL
}
};
diff --git a/include/hw/s390x/s390_flic.h b/include/hw/s390x/s390_flic.h
index 2f173d905c..7aab6ef7f0 100644
--- a/include/hw/s390x/s390_flic.h
+++ b/include/hw/s390x/s390_flic.h
@@ -89,6 +89,7 @@ typedef struct QEMUS390FLICState {
void s390_flic_init(void);
S390FLICState *s390_get_flic(void);
+bool ais_needed(void *opaque);
#ifdef CONFIG_KVM
DeviceState *s390_flic_kvm_create(void);