qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v4 04/10] cpu: introduce get_compat_arch_id() method


From: Zhu Guihua
Subject: [Qemu-devel] [PATCH v4 04/10] cpu: introduce get_compat_arch_id() method and override it for X86CPU
Date: Fri, 13 Feb 2015 18:25:27 +0800

get_compat_arch_id() is introduced to handle cross version migration issue,
it is to convert new 'apic-id' to old 'cpu_index'.

Signed-off-by: Zhu Guihua <address@hidden>
---
 include/qom/cpu.h      |  3 +++
 qom/cpu.c              |  6 ++++++
 target-i386/cpu.c      | 10 ++++++++++
 target-i386/topology.h | 33 +++++++++++++++++++++++++++++++++
 4 files changed, 52 insertions(+)

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 2098f1c..2e68dd2 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -86,6 +86,8 @@ struct TranslationBlock;
  * @dump_state: Callback for dumping state.
  * @dump_statistics: Callback for dumping statistics.
  * @get_arch_id: Callback for getting architecture-dependent CPU ID.
+ * @get_compat_arch_id: Callback for getting compatiable architecture-dependent
+ * CPU ID.
  * @get_paging_enabled: Callback for inquiring whether paging is enabled.
  * @get_memory_mapping: Callback for obtaining the memory mappings.
  * @set_pc: Callback for setting the Program Counter register.
@@ -130,6 +132,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_arch_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 9c68fa4..83d7766 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -321,6 +321,11 @@ static int64_t cpu_common_get_arch_id(CPUState *cpu)
     return cpu->cpu_index;
 }
 
+static int64_t cpu_common_get_compat_arch_id(CPUState *cpu)
+{
+    return cpu->cpu_index;
+}
+
 static void cpu_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -330,6 +335,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_arch_id = cpu_common_get_compat_arch_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 9e9f830..25f4f54 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2931,6 +2931,15 @@ static int64_t x86_cpu_get_arch_id(CPUState *cs)
     return env->cpuid_apic_id;
 }
 
+static int64_t x86_cpu_get_compat_arch_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);
@@ -3009,6 +3018,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_arch_id = x86_cpu_get_compat_arch_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 e9ff89c..6edd2c6 100644
--- a/target-i386/topology.h
+++ b/target-i386/topology.h
@@ -132,4 +132,37 @@ static inline apic_id_t x86_apicid_from_cpu_idx(unsigned 
nr_cores,
     return apicid_from_topo_ids(nr_cores, nr_threads, &topo);
 }
 
+/* Calculate CPU topology based on CPU APIC ID.
+ * + */
+static inline void x86_topo_ids_from_apic_id(unsigned nr_cores,
+                                             unsigned nr_threads,
+                                             apic_id_t apic_id,
+                                             X86CPUTopoInfo *topo)
+{
+    unsigned offset_mask;
+    topo->pkg_id = apic_id >> apicid_pkg_offset(nr_cores, nr_threads);
+
+    offset_mask = (1L << apicid_pkg_offset(nr_cores, nr_threads)) - 1;
+    topo->core_id = (apic_id & offset_mask)
+                     >> apicid_core_offset(nr_cores, nr_threads);
+
+    offset_mask = (1L << apicid_core_offset(nr_cores, nr_threads)) - 1;
+    topo->smt_id = apic_id & offset_mask;
+}
+
+/* Caculate CPU compat index based on CPU APIC ID.
+ */
+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 */
-- 
1.9.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]