qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [RFC PATCH] target-ppc: enable migration within the same CP


From: Alexey Kardashevskiy
Subject: [Qemu-devel] [RFC PATCH] target-ppc: enable migration within the same CPU family
Date: Mon, 24 Mar 2014 16:28:12 +1100

Currently only migration fails if CPU version is different even a bit.
For example, migration from POWER7 v2.0 to POWER7 v2.1 fails because of
that. Since there is no difference between CPU versions which could
affect migration stream, we can safely enable it.

This adds a helper to find the closest POWERPC family class (i.e. first
abstract class in hierarchy).

This replaces VMSTATE_UINTTL_EQUAL statement with a custom handler which
checks if the source and destination CPUs belong to the same family and
fails if they are not.

This adds a PVR reset to the default value as it will be overwritten
by VMSTATE_UINTTL_ARRAY(env.spr, PowerPCCPU, 1024).

Since the actual migration format is not changed by this patch,
@version_id of vmstate_ppc_cpu does not have to be changed either.

Signed-off-by: Bharata B Rao <address@hidden>
Signed-off-by: Alexey Kardashevskiy <address@hidden>
---
 target-ppc/cpu-qom.h        |  1 +
 target-ppc/machine.c        | 40 ++++++++++++++++++++++++++++++++++++++--
 target-ppc/translate_init.c | 12 ++++++++++++
 3 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
index 47dc8e6..5eb56ea 100644
--- a/target-ppc/cpu-qom.h
+++ b/target-ppc/cpu-qom.h
@@ -105,6 +105,7 @@ static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env)
 
 PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr);
 PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr);
+PowerPCCPUClass *ppc_cpu_family_class_by_pvr_mask(uint32_t pvr);
 
 void ppc_cpu_do_interrupt(CPUState *cpu);
 void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
diff --git a/target-ppc/machine.c b/target-ppc/machine.c
index 063b379..834297e 100644
--- a/target-ppc/machine.c
+++ b/target-ppc/machine.c
@@ -160,6 +160,11 @@ static int cpu_post_load(void *opaque, int version_id)
     CPUPPCState *env = &cpu->env;
     int i;
 
+    /*
+     * Allow migration between hosts of same processor family
+     * by restoring the default PVR for this VM on this host.
+     */
+    env->spr[SPR_PVR] = env->spr_cb[SPR_PVR].default_value;
     env->lr = env->spr[SPR_LR];
     env->ctr = env->spr[SPR_CTR];
     env->xer = env->spr[SPR_XER];
@@ -462,6 +467,37 @@ static const VMStateDescription vmstate_tlbmas = {
     }
 };
 
+static int get_pvr(QEMUFile *f, void *pv, size_t size)
+{
+    target_ulong pvrdest = *(target_ulong *)pv;
+#if TARGET_LONG_BITS == 64
+    target_ulong pvrsrc = qemu_get_be64(f);
+#else
+    target_ulong pvrsrc = qemu_get_be32(f);
+#endif
+    PowerPCCPUClass *pccdest = ppc_cpu_family_class_by_pvr_mask(pvrdest);
+    PowerPCCPUClass *pccsrc = ppc_cpu_family_class_by_pvr_mask(pvrsrc);
+
+    return (pccdest == pccsrc) ? 0 : -1;
+}
+
+static void put_pvr(QEMUFile *f, void *pv, size_t size)
+{
+    target_ulong pvr = *(target_ulong *)pv;
+
+#if TARGET_LONG_BITS == 64
+    qemu_put_be64(f, pvr);
+#else
+    qemu_put_be32(f, pvr);
+#endif
+}
+
+static const VMStateInfo vmstate_pvr = {
+    .name = "PVR",
+    .get  = get_pvr,
+    .put  = put_pvr,
+};
+
 const VMStateDescription vmstate_ppc_cpu = {
     .name = "cpu",
     .version_id = 5,
@@ -471,8 +507,8 @@ const VMStateDescription vmstate_ppc_cpu = {
     .pre_save = cpu_pre_save,
     .post_load = cpu_post_load,
     .fields      = (VMStateField []) {
-        /* Verify we haven't changed the pvr */
-        VMSTATE_UINTTL_EQUAL(env.spr[SPR_PVR], PowerPCCPU),
+        VMSTATE_SINGLE(env.spr[SPR_PVR], PowerPCCPU, 0, vmstate_pvr,
+                       target_ulong),
 
         /* User mode architected state */
         VMSTATE_UINTTL_ARRAY(env.gpr, PowerPCCPU, 32),
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index cdb2d2a..0c5c6a8 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8146,6 +8146,18 @@ PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr)
     return pcc;
 }
 
+PowerPCCPUClass *ppc_cpu_family_class_by_pvr_mask(uint32_t pvr)
+{
+    PowerPCCPUClass *pcc = ppc_cpu_class_by_pvr_mask(pvr);
+    ObjectClass *oc = OBJECT_CLASS(pcc);
+
+    while (oc && !object_class_is_abstract(oc)) {
+        oc = object_class_get_parent(oc);
+    }
+
+    return POWERPC_CPU_CLASS(oc);
+}
+
 static gint ppc_cpu_compare_class_name(gconstpointer a, gconstpointer b)
 {
     ObjectClass *oc = (ObjectClass *)a;
-- 
1.8.4.rc4




reply via email to

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