Looks like this patch broke migration from 2.10 to 2.9 (and older)
when ais is active. 

2.9 says
error while loading state for instance 0x0 of device 's390-flic'

So we need to fence this for older machines types than 2.10.
This should also go in 2.10.1.

Will have a look.



On 07/14/2017 12:41 PM, Christian Borntraeger wrote:
> From: Yi Min Zhao <zyi...@linux.vnet.ibm.com>
> 
> 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 <zyi...@linux.vnet.ibm.com>
> Signed-off-by: Christian Borntraeger <borntrae...@de.ibm.com>
> Reviewed-by: Cornelia Huck <coh...@redhat.com>
> ---
>  hw/intc/s390_flic.c          | 20 +++++++++++
>  hw/intc/s390_flic_kvm.c      | 81 
> ++++++++++++++++++++++++++++++++++++++++++++
>  include/hw/s390x/s390_flic.h |  1 +
>  3 files changed, 102 insertions(+)
> 
> diff --git a/hw/intc/s390_flic.c b/hw/intc/s390_flic.c
> index 6e7c610..6eaf178 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 d93503f..be3fd00 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 2f173d9..7aab6ef 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);
> 


Reply via email to