On Wed, 14 Jan 2015 15:27:25 +0800 Zhu Guihua <zhugh.f...@cn.fujitsu.com> wrote:
> From: Gu Zheng <guz.f...@cn.fujitsu.com> > > Move cpu vmstate register from cpu_exec_init into cpu_common_realizefn, > and use cc->get_arch_id as the instance id that suggested by Igor to > fix the migration issue. > > Signed-off-by: Gu Zheng <guz.f...@cn.fujitsu.com> > Signed-off-by: Zhu Guihua <zhugh.f...@cn.fujitsu.com> > --- > exec.c | 32 +++++++++++++++++++------------- > include/qom/cpu.h | 2 ++ > qom/cpu.c | 2 ++ > 3 files changed, 23 insertions(+), 13 deletions(-) > > diff --git a/exec.c b/exec.c > index 081818e..c9ffda6 100644 > --- a/exec.c > +++ b/exec.c > @@ -513,10 +513,28 @@ void tcg_cpu_address_space_init(CPUState *cpu, > AddressSpace *as) > } > #endif > > +void cpu_vmstate_register(CPUState *cpu) > +{ > + CPUClass *cc = CPU_GET_CLASS(cpu); > + int cpu_index = cc->get_arch_id(cpu); that probable would be source migration problems: because cc->get_arch_id(cpu) depending on topology might be not sequential, for example: sockets=4,core=3 that would create sparse APIC numbering. as result migration from old qemu to one with this change would be rejected due to vmsd id mismatch mismatch. we need a better way to handle cross version migration between old/new scheme. > + > + if (qdev_get_vmsd(DEVICE(cpu)) == NULL) { > + vmstate_register(NULL, cpu_index, &vmstate_cpu_common, cpu); > + } > +#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY) that ifdef block affects only sparc/mips/cris and builds target specific code while you are trying to call it from target independent qom/cpu.c I'd suggest leave it where it was or better move into respective targets realize_fns > + register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION, > + cpu_save, cpu_load, cpu->env_ptr); > + assert(cc->vmsd == NULL); > + assert(qdev_get_vmsd(DEVICE(cpu)) == NULL); > +#endif > + if (cc->vmsd != NULL) { > + vmstate_register(NULL, cpu_index, cc->vmsd, cpu); > + } > +} > + > void cpu_exec_init(CPUArchState *env) > { > CPUState *cpu = ENV_GET_CPU(env); > - CPUClass *cc = CPU_GET_CLASS(cpu); > CPUState *some_cpu; > int cpu_index; > > @@ -539,18 +557,6 @@ void cpu_exec_init(CPUArchState *env) > #if defined(CONFIG_USER_ONLY) > cpu_list_unlock(); > #endif > - if (qdev_get_vmsd(DEVICE(cpu)) == NULL) { > - vmstate_register(NULL, cpu_index, &vmstate_cpu_common, cpu); > - } > -#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY) > - register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION, > - cpu_save, cpu_load, env); > - assert(cc->vmsd == NULL); > - assert(qdev_get_vmsd(DEVICE(cpu)) == NULL); > -#endif > - if (cc->vmsd != NULL) { > - vmstate_register(NULL, cpu_index, cc->vmsd, cpu); > - } And in general do CONFIG_USER_ONLY targets actually need/use migration code? > } > > #if defined(TARGET_HAS_ICE) > diff --git a/include/qom/cpu.h b/include/qom/cpu.h > index 2098f1c..936afcd 100644 > --- a/include/qom/cpu.h > +++ b/include/qom/cpu.h > @@ -562,6 +562,8 @@ void cpu_interrupt(CPUState *cpu, int mask); > > #endif /* USER_ONLY */ > > +void cpu_vmstate_register(CPUState *cpu); > + > #ifdef CONFIG_SOFTMMU > static inline void cpu_unassigned_access(CPUState *cpu, hwaddr addr, > bool is_write, bool is_exec, > diff --git a/qom/cpu.c b/qom/cpu.c > index 9c68fa4..a639822 100644 > --- a/qom/cpu.c > +++ b/qom/cpu.c > @@ -302,6 +302,8 @@ static void cpu_common_realizefn(DeviceState *dev, Error > **errp) > { > CPUState *cpu = CPU(dev); > > + cpu_vmstate_register(cpu); > + > if (dev->hotplugged) { > cpu_synchronize_post_init(cpu); > cpu_resume(cpu);