Commit e7be8d49 authored by Yi Min Zhao's avatar Yi Min Zhao Committed by Christian Borntraeger
Browse files

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: default avatarYi Min Zhao <zyimin@linux.vnet.ibm.com>
Signed-off-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: default avatarCornelia Huck <cohuck@redhat.com>
parent 3b00f702
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -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;
+81 −0
Original line number Diff line number Diff line
@@ -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
    }
};

+1 −0
Original line number Diff line number Diff line
@@ -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);