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>
This commit is contained in:
Yi Min Zhao 2017-05-16 18:58:44 +08:00 committed by Christian Borntraeger
parent 3b00f702c2
commit e7be8d4997
3 changed files with 102 additions and 0 deletions

View File

@ -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;

View File

@ -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
}
};

View File

@ -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);