From 2c21ee769e4674348560480cecc7b20f3750ee84 Mon Sep 17 00:00:00 2001 From: Jianjun Duan Date: Thu, 19 Jan 2017 11:00:50 -0800 Subject: migration: extend VMStateInfo Current migration code cannot handle some data structures such as QTAILQ in qemu/queue.h. Here we extend the signatures of put/get in VMStateInfo so that customized handling is supported. put now will return int type. Reviewed-by: Dr. David Alan Gilbert Signed-off-by: Jianjun Duan Message-Id: <1484852453-12728-2-git-send-email-duanj@linux.vnet.ibm.com> Signed-off-by: Dr. David Alan Gilbert --- target/alpha/machine.c | 6 ++++-- target/arm/machine.c | 14 ++++++++++---- target/i386/machine.c | 26 +++++++++++++++++++------- target/mips/machine.c | 14 ++++++++++---- target/ppc/machine.c | 12 ++++++++---- target/sparc/machine.c | 6 ++++-- 6 files changed, 55 insertions(+), 23 deletions(-) (limited to 'target') diff --git a/target/alpha/machine.c b/target/alpha/machine.c index b99a123a39..a102645315 100644 --- a/target/alpha/machine.c +++ b/target/alpha/machine.c @@ -5,17 +5,19 @@ #include "hw/boards.h" #include "migration/cpu.h" -static int get_fpcr(QEMUFile *f, void *opaque, size_t size) +static int get_fpcr(QEMUFile *f, void *opaque, size_t size, VMStateField *field) { CPUAlphaState *env = opaque; cpu_alpha_store_fpcr(env, qemu_get_be64(f)); return 0; } -static void put_fpcr(QEMUFile *f, void *opaque, size_t size) +static int put_fpcr(QEMUFile *f, void *opaque, size_t size, + VMStateField *field, QJSON *vmdesc) { CPUAlphaState *env = opaque; qemu_put_be64(f, cpu_alpha_load_fpcr(env)); + return 0; } static const VMStateInfo vmstate_fpcr = { diff --git a/target/arm/machine.c b/target/arm/machine.c index d90943b6db..487320db1d 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -17,7 +17,8 @@ static bool vfp_needed(void *opaque) return arm_feature(env, ARM_FEATURE_VFP); } -static int get_fpscr(QEMUFile *f, void *opaque, size_t size) +static int get_fpscr(QEMUFile *f, void *opaque, size_t size, + VMStateField *field) { ARMCPU *cpu = opaque; CPUARMState *env = &cpu->env; @@ -27,12 +28,14 @@ static int get_fpscr(QEMUFile *f, void *opaque, size_t size) return 0; } -static void put_fpscr(QEMUFile *f, void *opaque, size_t size) +static int put_fpscr(QEMUFile *f, void *opaque, size_t size, + VMStateField *field, QJSON *vmdesc) { ARMCPU *cpu = opaque; CPUARMState *env = &cpu->env; qemu_put_be32(f, vfp_get_fpscr(env)); + return 0; } static const VMStateInfo vmstate_fpscr = { @@ -163,7 +166,8 @@ static const VMStateDescription vmstate_pmsav7 = { } }; -static int get_cpsr(QEMUFile *f, void *opaque, size_t size) +static int get_cpsr(QEMUFile *f, void *opaque, size_t size, + VMStateField *field) { ARMCPU *cpu = opaque; CPUARMState *env = &cpu->env; @@ -180,7 +184,8 @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size) return 0; } -static void put_cpsr(QEMUFile *f, void *opaque, size_t size) +static int put_cpsr(QEMUFile *f, void *opaque, size_t size, + VMStateField *field, QJSON *vmdesc) { ARMCPU *cpu = opaque; CPUARMState *env = &cpu->env; @@ -193,6 +198,7 @@ static void put_cpsr(QEMUFile *f, void *opaque, size_t size) } qemu_put_be32(f, val); + return 0; } static const VMStateInfo vmstate_cpsr = { diff --git a/target/i386/machine.c b/target/i386/machine.c index e002b4fc6d..78ae2f986b 100644 --- a/target/i386/machine.c +++ b/target/i386/machine.c @@ -136,10 +136,12 @@ static const VMStateDescription vmstate_mtrr_var = { #define VMSTATE_MTRR_VARS(_field, _state, _n, _v) \ VMSTATE_STRUCT_ARRAY(_field, _state, _n, _v, vmstate_mtrr_var, MTRRVar) -static void put_fpreg_error(QEMUFile *f, void *opaque, size_t size) +static int put_fpreg_error(QEMUFile *f, void *opaque, size_t size, + VMStateField *field, QJSON *vmdesc) { fprintf(stderr, "call put_fpreg() with invalid arguments\n"); exit(0); + return 0; } /* XXX: add that in a FPU generic layer */ @@ -164,7 +166,8 @@ static void fp64_to_fp80(union x86_longdouble *p, uint64_t temp) p->exp = e; } -static int get_fpreg(QEMUFile *f, void *opaque, size_t size) +static int get_fpreg(QEMUFile *f, void *opaque, size_t size, + VMStateField *field) { FPReg *fp_reg = opaque; uint64_t mant; @@ -176,7 +179,8 @@ static int get_fpreg(QEMUFile *f, void *opaque, size_t size) return 0; } -static void put_fpreg(QEMUFile *f, void *opaque, size_t size) +static int put_fpreg(QEMUFile *f, void *opaque, size_t size, + VMStateField *field, QJSON *vmdesc) { FPReg *fp_reg = opaque; uint64_t mant; @@ -186,6 +190,8 @@ static void put_fpreg(QEMUFile *f, void *opaque, size_t size) cpu_get_fp80(&mant, &exp, fp_reg->d); qemu_put_be64s(f, &mant); qemu_put_be16s(f, &exp); + + return 0; } static const VMStateInfo vmstate_fpreg = { @@ -194,7 +200,8 @@ static const VMStateInfo vmstate_fpreg = { .put = put_fpreg, }; -static int get_fpreg_1_mmx(QEMUFile *f, void *opaque, size_t size) +static int get_fpreg_1_mmx(QEMUFile *f, void *opaque, size_t size, + VMStateField *field) { union x86_longdouble *p = opaque; uint64_t mant; @@ -211,7 +218,8 @@ static const VMStateInfo vmstate_fpreg_1_mmx = { .put = put_fpreg_error, }; -static int get_fpreg_1_no_mmx(QEMUFile *f, void *opaque, size_t size) +static int get_fpreg_1_no_mmx(QEMUFile *f, void *opaque, size_t size, + VMStateField *field) { union x86_longdouble *p = opaque; uint64_t mant; @@ -273,17 +281,21 @@ static bool less_than_7(void *opaque, int version_id) return version_id < 7; } -static int get_uint64_as_uint32(QEMUFile *f, void *pv, size_t size) +static int get_uint64_as_uint32(QEMUFile *f, void *pv, size_t size, + VMStateField *field) { uint64_t *v = pv; *v = qemu_get_be32(f); return 0; } -static void put_uint64_as_uint32(QEMUFile *f, void *pv, size_t size) +static int put_uint64_as_uint32(QEMUFile *f, void *pv, size_t size, + VMStateField *field, QJSON *vmdesc) { uint64_t *v = pv; qemu_put_be32(f, *v); + + return 0; } static const VMStateInfo vmstate_hack_uint64_as_uint32 = { diff --git a/target/mips/machine.c b/target/mips/machine.c index d20d948457..38c8fe9328 100644 --- a/target/mips/machine.c +++ b/target/mips/machine.c @@ -19,7 +19,7 @@ static int cpu_post_load(void *opaque, int version_id) /* FPU state */ -static int get_fpr(QEMUFile *f, void *pv, size_t size) +static int get_fpr(QEMUFile *f, void *pv, size_t size, VMStateField *field) { int i; fpr_t *v = pv; @@ -30,7 +30,8 @@ static int get_fpr(QEMUFile *f, void *pv, size_t size) return 0; } -static void put_fpr(QEMUFile *f, void *pv, size_t size) +static int put_fpr(QEMUFile *f, void *pv, size_t size, VMStateField *field, + QJSON *vmdesc) { int i; fpr_t *v = pv; @@ -38,6 +39,8 @@ static void put_fpr(QEMUFile *f, void *pv, size_t size) for (i = 0; i < MSA_WRLEN/64; i++) { qemu_put_sbe64s(f, &v->wr.d[i]); } + + return 0; } const VMStateInfo vmstate_info_fpr = { @@ -124,7 +127,7 @@ const VMStateDescription vmstate_mvp = { /* TLB state */ -static int get_tlb(QEMUFile *f, void *pv, size_t size) +static int get_tlb(QEMUFile *f, void *pv, size_t size, VMStateField *field) { r4k_tlb_t *v = pv; uint16_t flags; @@ -151,7 +154,8 @@ static int get_tlb(QEMUFile *f, void *pv, size_t size) return 0; } -static void put_tlb(QEMUFile *f, void *pv, size_t size) +static int put_tlb(QEMUFile *f, void *pv, size_t size, VMStateField *field, + QJSON *vmdesc) { r4k_tlb_t *v = pv; @@ -175,6 +179,8 @@ static void put_tlb(QEMUFile *f, void *pv, size_t size) qemu_put_be16s(f, &flags); qemu_put_be64s(f, &v->PFN[0]); qemu_put_be64s(f, &v->PFN[1]); + + return 0; } const VMStateInfo vmstate_info_tlb = { diff --git a/target/ppc/machine.c b/target/ppc/machine.c index 18c16d2512..df9f7a4e05 100644 --- a/target/ppc/machine.c +++ b/target/ppc/machine.c @@ -105,7 +105,7 @@ static int cpu_load_old(QEMUFile *f, void *opaque, int version_id) return 0; } -static int get_avr(QEMUFile *f, void *pv, size_t size) +static int get_avr(QEMUFile *f, void *pv, size_t size, VMStateField *field) { ppc_avr_t *v = pv; @@ -115,12 +115,14 @@ static int get_avr(QEMUFile *f, void *pv, size_t size) return 0; } -static void put_avr(QEMUFile *f, void *pv, size_t size) +static int put_avr(QEMUFile *f, void *pv, size_t size, VMStateField *field, + QJSON *vmdesc) { ppc_avr_t *v = pv; qemu_put_be64(f, v->u64[0]); qemu_put_be64(f, v->u64[1]); + return 0; } static const VMStateInfo vmstate_info_avr = { @@ -353,7 +355,7 @@ static const VMStateDescription vmstate_sr = { }; #ifdef TARGET_PPC64 -static int get_slbe(QEMUFile *f, void *pv, size_t size) +static int get_slbe(QEMUFile *f, void *pv, size_t size, VMStateField *field) { ppc_slb_t *v = pv; @@ -363,12 +365,14 @@ static int get_slbe(QEMUFile *f, void *pv, size_t size) return 0; } -static void put_slbe(QEMUFile *f, void *pv, size_t size) +static int put_slbe(QEMUFile *f, void *pv, size_t size, VMStateField *field, + QJSON *vmdesc) { ppc_slb_t *v = pv; qemu_put_be64(f, v->esid); qemu_put_be64(f, v->vsid); + return 0; } static const VMStateInfo vmstate_info_slbe = { diff --git a/target/sparc/machine.c b/target/sparc/machine.c index 39e262ccd1..6bd6b8ee3e 100644 --- a/target/sparc/machine.c +++ b/target/sparc/machine.c @@ -56,7 +56,7 @@ static const VMStateDescription vmstate_tlb_entry = { }; #endif -static int get_psr(QEMUFile *f, void *opaque, size_t size) +static int get_psr(QEMUFile *f, void *opaque, size_t size, VMStateField *field) { SPARCCPU *cpu = opaque; CPUSPARCState *env = &cpu->env; @@ -69,7 +69,8 @@ static int get_psr(QEMUFile *f, void *opaque, size_t size) return 0; } -static void put_psr(QEMUFile *f, void *opaque, size_t size) +static int put_psr(QEMUFile *f, void *opaque, size_t size, VMStateField *field, + QJSON *vmdesc) { SPARCCPU *cpu = opaque; CPUSPARCState *env = &cpu->env; @@ -78,6 +79,7 @@ static void put_psr(QEMUFile *f, void *opaque, size_t size) val = cpu_get_psr(env); qemu_put_be32(f, val); + return 0; } static const VMStateInfo vmstate_psr = { -- cgit v1.2.3 From fe44dc91807eca59d0230fe828c1e2ee0c305a1e Mon Sep 17 00:00:00 2001 From: Ashijeet Acharya Date: Mon, 16 Jan 2017 17:01:53 +0530 Subject: migration: disallow migrate_add_blocker during migration If a migration is already in progress and somebody attempts to add a migration blocker, this should rightly fail. Add an errp parameter and a retcode return value to migrate_add_blocker. Signed-off-by: John Snow Signed-off-by: Ashijeet Acharya Message-Id: <1484566314-3987-5-git-send-email-ashijeetacharya@gmail.com> Reviewed-by: Dr. David Alan Gilbert Acked-by: Greg Kurz Signed-off-by: Dr. David Alan Gilbert Merged with recent 'Allow invtsc migration' change --- target/i386/kvm.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'target') diff --git a/target/i386/kvm.c b/target/i386/kvm.c index 3b5282186c..8e130ccf9c 100644 --- a/target/i386/kvm.c +++ b/target/i386/kvm.c @@ -710,6 +710,7 @@ int kvm_arch_init_vcpu(CPUState *cs) uint32_t signature[3]; int kvm_base = KVM_CPUID_SIGNATURE; int r; + Error *local_err = NULL; memset(&cpuid_data, 0, sizeof(cpuid_data)); @@ -970,7 +971,12 @@ int kvm_arch_init_vcpu(CPUState *cs) error_setg(&invtsc_mig_blocker, "State blocked by non-migratable CPU device" " (invtsc flag)"); - migrate_add_blocker(invtsc_mig_blocker); + r = migrate_add_blocker(invtsc_mig_blocker, &local_err); + if (local_err) { + error_report_err(local_err); + error_free(invtsc_mig_blocker); + goto fail; + } /* for savevm */ vmstate_x86_cpu.unmigratable = 1; } @@ -979,12 +985,12 @@ int kvm_arch_init_vcpu(CPUState *cs) cpuid_data.cpuid.padding = 0; r = kvm_vcpu_ioctl(cs, KVM_SET_CPUID2, &cpuid_data); if (r) { - return r; + goto fail; } r = kvm_arch_set_tsc_khz(cs); if (r < 0) { - return r; + goto fail; } /* vcpu's TSC frequency is either specified by user, or following @@ -1011,6 +1017,10 @@ int kvm_arch_init_vcpu(CPUState *cs) } return 0; + + fail: + migrate_del_blocker(invtsc_mig_blocker); + return r; } void kvm_arch_reset_vcpu(X86CPU *cpu) -- cgit v1.2.3