When a vmstate for the ppc cpu was first introduced (a90db15 "target-ppc: Convert ppc cpu savevm to VMStateDescription"), a VMSTATE_EQUAL was used to ensure that identical CPU models were used at source and destination as based on the PVR (Processor Version Register).
However this was a problem for HV KVM, where due to hardware limitations we always need to use the real PVR of the host CPU. So, to allow migration between hosts with "similar enough" CPUs, the PVR check was removed in 569be9f0 "target-ppc: Remove PVR check from migration". This left the onus on user / management to only attempt migration between compatible CPUs. Now that we've reworked the handling of compatiblity modes, we have the information to actually determine if we're making a compatible migration. So this patch partially restores the PVR check. If the source was running in a compatibility mode, we just make sure that the destination cpu can also run in that compatibility mode. However, if the source was running in "raw" mode, we verify that the destination has the same PVR value. Signed-off-by: David Gibson <da...@gibson.dropbear.id.au> --- target-ppc/machine.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/target-ppc/machine.c b/target-ppc/machine.c index 5d87ff6..62b9e94 100644 --- a/target-ppc/machine.c +++ b/target-ppc/machine.c @@ -173,10 +173,12 @@ static int cpu_post_load(void *opaque, int version_id) target_ulong msr; /* - * We always ignore the source PVR. The user or management - * software has to take care of running QEMU in a compatible mode. + * If we're operating in compat mode, we should be ok as long as + * the destination supports the same compatiblity mode. + * + * Otherwise, however, we require that the destination has exactly + * the same CPU model as the source. */ - env->spr[SPR_PVR] = env->spr_cb[SPR_PVR].default_value; #if defined(TARGET_PPC64) if (cpu->compat_pvr) { @@ -188,8 +190,13 @@ static int cpu_post_load(void *opaque, int version_id) error_free(local_err); return -1; } - } + } else #endif + { + if (env->spr[SPR_PVR] != env->spr_cb[SPR_PVR].default_value) { + return -1; + } + } env->lr = env->spr[SPR_LR]; env->ctr = env->spr[SPR_CTR]; -- 2.7.4