diff --git a/exec.c b/exec.c index bda96c6..6f3a90d 100644 --- a/exec.c +++ b/exec.c @@ -516,10 +516,12 @@ void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as) void cpu_vmstate_register(CPUState *cpu) { CPUClass *cc = CPU_GET_CLASS(cpu); - int cpu_index = cc->get_arch_id(cpu); + int cpu_index = cc->get_arch_id(cpu) + max_cpus; + int compat_index = cc->get_compat_id(cpu); if (qdev_get_vmsd(DEVICE(cpu)) == NULL) { - vmstate_register(NULL, cpu_index, &vmstate_cpu_common, cpu); + vmstate_register_with_alias_id(NULL, cpu_index, &vmstate_cpu_common, + cpu, compat_index, 3); } #if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY) register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION, @@ -528,7 +530,8 @@ void cpu_vmstate_register(CPUState *cpu) assert(qdev_get_vmsd(DEVICE(cpu)) == NULL); #endif if (cc->vmsd != NULL) { - vmstate_register(NULL, cpu_index, cc->vmsd, cpu); + vmstate_register_with_alias_id(NULL, cpu_index, cc->vmsd, + cpu, compat_index, 3); } } diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 0592b4d..3d0bcbf 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -130,6 +130,7 @@ typedef struct CPUClass { void (*dump_statistics)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); int64_t (*get_arch_id)(CPUState *cpu); + int64_t (*get_compat_id)(CPUState *cpu); bool (*get_paging_enabled)(const CPUState *cpu); void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list, Error **errp); diff --git a/qom/cpu.c b/qom/cpu.c index a639822..48dee41 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -323,6 +323,11 @@ static int64_t cpu_common_get_arch_id(CPUState *cpu) return cpu->cpu_index; } +static int64_t cpu_common_get_compat_id(CPUState *cpu) +{ + return cpu->cpu_index; +} + static void cpu_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -332,6 +337,7 @@ static void cpu_class_init(ObjectClass *klass, void *data) k->parse_features = cpu_common_parse_features; k->reset = cpu_common_reset; k->get_arch_id = cpu_common_get_arch_id; + k->get_compat_id = cpu_common_get_compat_id; k->has_work = cpu_common_has_work; k->get_paging_enabled = cpu_common_get_paging_enabled; k->get_memory_mapping = cpu_common_get_memory_mapping; diff --git a/target-i386/cpu.c b/target-i386/cpu.c index e25789a..8c024b9 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2794,13 +2794,15 @@ static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp) { DeviceState *apic_state = cpu->apic_state; CPUClass *cc = CPU_GET_CLASS(CPU(cpu)); + int cpu_index = cc->get_arch_id(CPU(cpu)) + max_cpus; + int compat_index = cc->get_compat_id(CPU(cpu)); if (apic_state == NULL) { return; } - vmstate_register(0, cc->get_arch_id(CPU(cpu)), - &vmstate_apic_common, apic_state); + vmstate_register_with_alias_id(NULL, cpu_index, &vmstate_apic_common, + apic_state, compat_index, 3); if (qdev_init(cpu->apic_state)) { error_setg(errp, "APIC device '%s' could not be initialized", @@ -3042,6 +3044,15 @@ static int64_t x86_cpu_get_arch_id(CPUState *cs) return env->cpuid_apic_id; } +static int64_t x86_cpu_get_compat_id(CPUState *cs) +{ + X86CPU *cpu = X86_CPU(cs); + CPUX86State *env = &cpu->env; + + return x86_compat_index_from_apic_id(smp_cores, smp_threads, + env->cpuid_apic_id); +} + static bool x86_cpu_get_paging_enabled(const CPUState *cs) { X86CPU *cpu = X86_CPU(cs); @@ -3122,6 +3133,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) cc->gdb_read_register = x86_cpu_gdb_read_register; cc->gdb_write_register = x86_cpu_gdb_write_register; cc->get_arch_id = x86_cpu_get_arch_id; + cc->get_compat_id = x86_cpu_get_compat_id; cc->get_paging_enabled = x86_cpu_get_paging_enabled; #ifdef CONFIG_USER_ONLY cc->handle_mmu_fault = x86_cpu_handle_mmu_fault; diff --git a/target-i386/topology.h b/target-i386/topology.h index dcb4988..42d1d07 100644 --- a/target-i386/topology.h +++ b/target-i386/topology.h @@ -150,4 +150,20 @@ static inline void x86_topo_ids_from_apic_id(unsigned nr_cores, topo->smt_id = apic_id & offset_mask; } +static inline unsigned x86_compat_index_from_apic_id(unsigned nr_cores, + unsigned nr_threads, + apic_id_t apic_id) +{ + X86CPUTopoInfo topo; + + x86_topo_ids_from_apic_id(nr_cores, nr_threads, apic_id, &topo); + + + return topo.pkg_id * nr_cores * nr_threads + + topo.core_id * nr_threads + + topo.smt_id; +} + + + #endif /* TARGET_I386_TOPOLOGY_H */