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:
parent
3b00f702c2
commit
e7be8d4997
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user