Message ID | 1479706302-2251-2-git-send-email-david@gibson.dropbear.id.au |
---|---|
State | New |
Headers | show |
* David Gibson (david@gibson.dropbear.id.au) wrote: > When migration for target-ppc was converted to vmstate, several > VMSTATE_EQUAL() checks were foolishly included of things that really > should be internal state. Specifically we verified equality of the > insns_flags and insns_flags2 fields, which are used within TCG to > determine which groups of instructions are available on this cpu > model. Between qemu-2.6 and qemu-2.7 we made some changes to these > classes which broke migration. > > This path fixes migration both forwards and backwards. On migration > from 2.6 to later versions we import the fields into teporary > variables, which we then ignore. In migration backwards, we populate > the temporary fields from the runtime fields, but mask out the bits > which were added after qemu-2.6, allowing the VMSTATE_EQUAL in > qemu-2.6 to accept the stream. > > Signed-off-by: David Gibson <david@gibson.dropbear.id.au> From the migration side of things without knowing the ppc flags: Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> > --- > target-ppc/cpu.h | 6 ++++++ > target-ppc/machine.c | 29 +++++++++++++++++++++++++---- > 2 files changed, 31 insertions(+), 4 deletions(-) > > diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h > index 1c90adb..7798b2e 100644 > --- a/target-ppc/cpu.h > +++ b/target-ppc/cpu.h > @@ -1166,6 +1166,12 @@ struct PowerPCCPU { > int cpu_dt_id; > uint32_t max_compat; > uint32_t cpu_version; > + > + /* fields used only during migration for compatibility hacks */ > + target_ulong mig_msr_mask; > + uint64_t mig_insns_flags; > + uint64_t mig_insns_flags2; > + uint32_t mig_nb_BATs; > }; > > static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env) > diff --git a/target-ppc/machine.c b/target-ppc/machine.c > index e43cb6c..fcac263 100644 > --- a/target-ppc/machine.c > +++ b/target-ppc/machine.c > @@ -140,6 +140,21 @@ static void cpu_pre_save(void *opaque) > PowerPCCPU *cpu = opaque; > CPUPPCState *env = &cpu->env; > int i; > + uint64_t insns_compat_mask = > + PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB > + | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES > + | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | PPC_FLOAT_FRSQRTES > + | PPC_FLOAT_STFIWX | PPC_FLOAT_EXT > + | PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ > + | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC > + | PPC_64B | PPC_64BX | PPC_ALTIVEC > + | PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD; > + uint64_t insns_compat_mask2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX > + | PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 > + | PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 > + | PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 > + | PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 > + | PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | PPC2_TM; > > env->spr[SPR_LR] = env->lr; > env->spr[SPR_CTR] = env->ctr; > @@ -161,6 +176,12 @@ static void cpu_pre_save(void *opaque) > env->spr[SPR_IBAT4U + 2*i] = env->IBAT[0][i+4]; > env->spr[SPR_IBAT4U + 2*i + 1] = env->IBAT[1][i+4]; > } > + > + /* Hacks for migration compatibility between 2.6, 2.7 & 2.8 */ > + cpu->mig_msr_mask = env->msr_mask; > + cpu->mig_insns_flags = env->insns_flags & insns_compat_mask; > + cpu->mig_insns_flags2 = env->insns_flags2 & insns_compat_mask2; > + cpu->mig_nb_BATs = env->nb_BATs; > } > > static int cpu_post_load(void *opaque, int version_id) > @@ -561,10 +582,10 @@ const VMStateDescription vmstate_ppc_cpu = { > /* FIXME: access_type? */ > > /* Sanity checking */ > - VMSTATE_UINTTL_EQUAL(env.msr_mask, PowerPCCPU), > - VMSTATE_UINT64_EQUAL(env.insns_flags, PowerPCCPU), > - VMSTATE_UINT64_EQUAL(env.insns_flags2, PowerPCCPU), > - VMSTATE_UINT32_EQUAL(env.nb_BATs, PowerPCCPU), > + VMSTATE_UINTTL(mig_msr_mask, PowerPCCPU), > + VMSTATE_UINT64(mig_insns_flags, PowerPCCPU), > + VMSTATE_UINT64(mig_insns_flags2, PowerPCCPU), > + VMSTATE_UINT32(mig_nb_BATs, PowerPCCPU), > VMSTATE_END_OF_LIST() > }, > .subsections = (const VMStateDescription*[]) { > -- > 2.7.4 > -- Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
On 21.11.2016 06:31, David Gibson wrote: > When migration for target-ppc was converted to vmstate, several > VMSTATE_EQUAL() checks were foolishly included of things that really > should be internal state. Specifically we verified equality of the > insns_flags and insns_flags2 fields, which are used within TCG to > determine which groups of instructions are available on this cpu > model. Between qemu-2.6 and qemu-2.7 we made some changes to these > classes which broke migration. > > This path fixes migration both forwards and backwards. On migration > from 2.6 to later versions we import the fields into teporary > variables, which we then ignore. In migration backwards, we populate > the temporary fields from the runtime fields, but mask out the bits > which were added after qemu-2.6, allowing the VMSTATE_EQUAL in > qemu-2.6 to accept the stream. > > Signed-off-by: David Gibson <david@gibson.dropbear.id.au> > --- > target-ppc/cpu.h | 6 ++++++ > target-ppc/machine.c | 29 +++++++++++++++++++++++++---- > 2 files changed, 31 insertions(+), 4 deletions(-) > > diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h > index 1c90adb..7798b2e 100644 > --- a/target-ppc/cpu.h > +++ b/target-ppc/cpu.h > @@ -1166,6 +1166,12 @@ struct PowerPCCPU { > int cpu_dt_id; > uint32_t max_compat; > uint32_t cpu_version; > + > + /* fields used only during migration for compatibility hacks */ > + target_ulong mig_msr_mask; > + uint64_t mig_insns_flags; > + uint64_t mig_insns_flags2; > + uint32_t mig_nb_BATs; > }; > > static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env) > diff --git a/target-ppc/machine.c b/target-ppc/machine.c > index e43cb6c..fcac263 100644 > --- a/target-ppc/machine.c > +++ b/target-ppc/machine.c > @@ -140,6 +140,21 @@ static void cpu_pre_save(void *opaque) > PowerPCCPU *cpu = opaque; > CPUPPCState *env = &cpu->env; > int i; > + uint64_t insns_compat_mask = > + PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB > + | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES > + | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | PPC_FLOAT_FRSQRTES > + | PPC_FLOAT_STFIWX | PPC_FLOAT_EXT > + | PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ > + | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC > + | PPC_64B | PPC_64BX | PPC_ALTIVEC > + | PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD; > + uint64_t insns_compat_mask2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX > + | PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 > + | PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 > + | PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 > + | PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 > + | PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | PPC2_TM; > > env->spr[SPR_LR] = env->lr; > env->spr[SPR_CTR] = env->ctr; > @@ -161,6 +176,12 @@ static void cpu_pre_save(void *opaque) > env->spr[SPR_IBAT4U + 2*i] = env->IBAT[0][i+4]; > env->spr[SPR_IBAT4U + 2*i + 1] = env->IBAT[1][i+4]; > } > + > + /* Hacks for migration compatibility between 2.6, 2.7 & 2.8 */ > + cpu->mig_msr_mask = env->msr_mask; > + cpu->mig_insns_flags = env->insns_flags & insns_compat_mask; > + cpu->mig_insns_flags2 = env->insns_flags2 & insns_compat_mask2; > + cpu->mig_nb_BATs = env->nb_BATs; > } > > static int cpu_post_load(void *opaque, int version_id) > @@ -561,10 +582,10 @@ const VMStateDescription vmstate_ppc_cpu = { > /* FIXME: access_type? */ > > /* Sanity checking */ > - VMSTATE_UINTTL_EQUAL(env.msr_mask, PowerPCCPU), > - VMSTATE_UINT64_EQUAL(env.insns_flags, PowerPCCPU), > - VMSTATE_UINT64_EQUAL(env.insns_flags2, PowerPCCPU), > - VMSTATE_UINT32_EQUAL(env.nb_BATs, PowerPCCPU), > + VMSTATE_UINTTL(mig_msr_mask, PowerPCCPU), > + VMSTATE_UINT64(mig_insns_flags, PowerPCCPU), > + VMSTATE_UINT64(mig_insns_flags2, PowerPCCPU), > + VMSTATE_UINT32(mig_nb_BATs, PowerPCCPU), > VMSTATE_END_OF_LIST() > }, > .subsections = (const VMStateDescription*[]) { > Looks fine to me. Reviewed-by: Thomas Huth <thuth@redhat.com>
On Mon, 21 Nov 2016 16:31:38 +1100 David Gibson <david@gibson.dropbear.id.au> wrote: > When migration for target-ppc was converted to vmstate, several > VMSTATE_EQUAL() checks were foolishly included of things that really > should be internal state. Specifically we verified equality of the > insns_flags and insns_flags2 fields, which are used within TCG to > determine which groups of instructions are available on this cpu > model. Between qemu-2.6 and qemu-2.7 we made some changes to these > classes which broke migration. > > This path fixes migration both forwards and backwards. On migration > from 2.6 to later versions we import the fields into teporary > variables, which we then ignore. In migration backwards, we populate > the temporary fields from the runtime fields, but mask out the bits > which were added after qemu-2.6, allowing the VMSTATE_EQUAL in > qemu-2.6 to accept the stream. > > Signed-off-by: David Gibson <david@gibson.dropbear.id.au> > --- Reviewed-by: Greg Kurz <groug@kaod.org> > target-ppc/cpu.h | 6 ++++++ > target-ppc/machine.c | 29 +++++++++++++++++++++++++---- > 2 files changed, 31 insertions(+), 4 deletions(-) > > diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h > index 1c90adb..7798b2e 100644 > --- a/target-ppc/cpu.h > +++ b/target-ppc/cpu.h > @@ -1166,6 +1166,12 @@ struct PowerPCCPU { > int cpu_dt_id; > uint32_t max_compat; > uint32_t cpu_version; > + > + /* fields used only during migration for compatibility hacks */ > + target_ulong mig_msr_mask; > + uint64_t mig_insns_flags; > + uint64_t mig_insns_flags2; > + uint32_t mig_nb_BATs; > }; > > static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env) > diff --git a/target-ppc/machine.c b/target-ppc/machine.c > index e43cb6c..fcac263 100644 > --- a/target-ppc/machine.c > +++ b/target-ppc/machine.c > @@ -140,6 +140,21 @@ static void cpu_pre_save(void *opaque) > PowerPCCPU *cpu = opaque; > CPUPPCState *env = &cpu->env; > int i; > + uint64_t insns_compat_mask = > + PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB > + | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES > + | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | PPC_FLOAT_FRSQRTES > + | PPC_FLOAT_STFIWX | PPC_FLOAT_EXT > + | PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ > + | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC > + | PPC_64B | PPC_64BX | PPC_ALTIVEC > + | PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD; > + uint64_t insns_compat_mask2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX > + | PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 > + | PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 > + | PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 > + | PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 > + | PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | PPC2_TM; > > env->spr[SPR_LR] = env->lr; > env->spr[SPR_CTR] = env->ctr; > @@ -161,6 +176,12 @@ static void cpu_pre_save(void *opaque) > env->spr[SPR_IBAT4U + 2*i] = env->IBAT[0][i+4]; > env->spr[SPR_IBAT4U + 2*i + 1] = env->IBAT[1][i+4]; > } > + > + /* Hacks for migration compatibility between 2.6, 2.7 & 2.8 */ > + cpu->mig_msr_mask = env->msr_mask; > + cpu->mig_insns_flags = env->insns_flags & insns_compat_mask; > + cpu->mig_insns_flags2 = env->insns_flags2 & insns_compat_mask2; > + cpu->mig_nb_BATs = env->nb_BATs; > } > > static int cpu_post_load(void *opaque, int version_id) > @@ -561,10 +582,10 @@ const VMStateDescription vmstate_ppc_cpu = { > /* FIXME: access_type? */ > > /* Sanity checking */ > - VMSTATE_UINTTL_EQUAL(env.msr_mask, PowerPCCPU), > - VMSTATE_UINT64_EQUAL(env.insns_flags, PowerPCCPU), > - VMSTATE_UINT64_EQUAL(env.insns_flags2, PowerPCCPU), > - VMSTATE_UINT32_EQUAL(env.nb_BATs, PowerPCCPU), > + VMSTATE_UINTTL(mig_msr_mask, PowerPCCPU), > + VMSTATE_UINT64(mig_insns_flags, PowerPCCPU), > + VMSTATE_UINT64(mig_insns_flags2, PowerPCCPU), > + VMSTATE_UINT32(mig_nb_BATs, PowerPCCPU), > VMSTATE_END_OF_LIST() > }, > .subsections = (const VMStateDescription*[]) {
On 21/11/16 16:31, David Gibson wrote: > When migration for target-ppc was converted to vmstate, several > VMSTATE_EQUAL() checks were foolishly included of things that really > should be internal state. Specifically we verified equality of the > insns_flags and insns_flags2 fields, which are used within TCG to > determine which groups of instructions are available on this cpu > model. Between qemu-2.6 and qemu-2.7 we made some changes to these > classes which broke migration. > > This path fixes migration both forwards and backwards. On migration > from 2.6 to later versions we import the fields into teporary > variables, which we then ignore. In migration backwards, we populate > the temporary fields from the runtime fields, but mask out the bits > which were added after qemu-2.6, allowing the VMSTATE_EQUAL in > qemu-2.6 to accept the stream. > > Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru> One question though - do we care about TCG migration at all? If so, we could want to migrate these bits, just not with _EQUAL but rather check that the source does not have bits which are not supported by the destination. > --- > target-ppc/cpu.h | 6 ++++++ > target-ppc/machine.c | 29 +++++++++++++++++++++++++---- > 2 files changed, 31 insertions(+), 4 deletions(-) > > diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h > index 1c90adb..7798b2e 100644 > --- a/target-ppc/cpu.h > +++ b/target-ppc/cpu.h > @@ -1166,6 +1166,12 @@ struct PowerPCCPU { > int cpu_dt_id; > uint32_t max_compat; > uint32_t cpu_version; > + > + /* fields used only during migration for compatibility hacks */ > + target_ulong mig_msr_mask; > + uint64_t mig_insns_flags; > + uint64_t mig_insns_flags2; > + uint32_t mig_nb_BATs; > }; > > static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env) > diff --git a/target-ppc/machine.c b/target-ppc/machine.c > index e43cb6c..fcac263 100644 > --- a/target-ppc/machine.c > +++ b/target-ppc/machine.c > @@ -140,6 +140,21 @@ static void cpu_pre_save(void *opaque) > PowerPCCPU *cpu = opaque; > CPUPPCState *env = &cpu->env; > int i; > + uint64_t insns_compat_mask = > + PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB > + | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES > + | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | PPC_FLOAT_FRSQRTES > + | PPC_FLOAT_STFIWX | PPC_FLOAT_EXT > + | PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ > + | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC > + | PPC_64B | PPC_64BX | PPC_ALTIVEC > + | PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD; > + uint64_t insns_compat_mask2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX > + | PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 > + | PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 > + | PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 > + | PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 > + | PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | PPC2_TM; > > env->spr[SPR_LR] = env->lr; > env->spr[SPR_CTR] = env->ctr; > @@ -161,6 +176,12 @@ static void cpu_pre_save(void *opaque) > env->spr[SPR_IBAT4U + 2*i] = env->IBAT[0][i+4]; > env->spr[SPR_IBAT4U + 2*i + 1] = env->IBAT[1][i+4]; > } > + > + /* Hacks for migration compatibility between 2.6, 2.7 & 2.8 */ > + cpu->mig_msr_mask = env->msr_mask; > + cpu->mig_insns_flags = env->insns_flags & insns_compat_mask; > + cpu->mig_insns_flags2 = env->insns_flags2 & insns_compat_mask2; > + cpu->mig_nb_BATs = env->nb_BATs; > } > > static int cpu_post_load(void *opaque, int version_id) > @@ -561,10 +582,10 @@ const VMStateDescription vmstate_ppc_cpu = { > /* FIXME: access_type? */ > > /* Sanity checking */ > - VMSTATE_UINTTL_EQUAL(env.msr_mask, PowerPCCPU), > - VMSTATE_UINT64_EQUAL(env.insns_flags, PowerPCCPU), > - VMSTATE_UINT64_EQUAL(env.insns_flags2, PowerPCCPU), > - VMSTATE_UINT32_EQUAL(env.nb_BATs, PowerPCCPU), > + VMSTATE_UINTTL(mig_msr_mask, PowerPCCPU), > + VMSTATE_UINT64(mig_insns_flags, PowerPCCPU), > + VMSTATE_UINT64(mig_insns_flags2, PowerPCCPU), > + VMSTATE_UINT32(mig_nb_BATs, PowerPCCPU), > VMSTATE_END_OF_LIST() > }, > .subsections = (const VMStateDescription*[]) { >
On Tue, Nov 22, 2016 at 07:19:38PM +1100, Alexey Kardashevskiy wrote: > On 21/11/16 16:31, David Gibson wrote: > > When migration for target-ppc was converted to vmstate, several > > VMSTATE_EQUAL() checks were foolishly included of things that really > > should be internal state. Specifically we verified equality of the > > insns_flags and insns_flags2 fields, which are used within TCG to > > determine which groups of instructions are available on this cpu > > model. Between qemu-2.6 and qemu-2.7 we made some changes to these > > classes which broke migration. > > > > This path fixes migration both forwards and backwards. On migration > > from 2.6 to later versions we import the fields into teporary > > variables, which we then ignore. In migration backwards, we populate > > the temporary fields from the runtime fields, but mask out the bits > > which were added after qemu-2.6, allowing the VMSTATE_EQUAL in > > qemu-2.6 to accept the stream. > > > > Signed-off-by: David Gibson <david@gibson.dropbear.id.au> > > > Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru> > > One question though - do we care about TCG migration at all? If so, we > could want to migrate these bits, just not with _EQUAL but rather check > that the source does not have bits which are not supported by the > destination. Yes, we do care about TCG migration, but the conclusion doesn't follow. insns_flags is a qemu internal representation, not anything architected, and it never changes during runtime. We should be free to change that representation, and as long as the CPUs are compatible it should still work.
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 1c90adb..7798b2e 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1166,6 +1166,12 @@ struct PowerPCCPU { int cpu_dt_id; uint32_t max_compat; uint32_t cpu_version; + + /* fields used only during migration for compatibility hacks */ + target_ulong mig_msr_mask; + uint64_t mig_insns_flags; + uint64_t mig_insns_flags2; + uint32_t mig_nb_BATs; }; static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env) diff --git a/target-ppc/machine.c b/target-ppc/machine.c index e43cb6c..fcac263 100644 --- a/target-ppc/machine.c +++ b/target-ppc/machine.c @@ -140,6 +140,21 @@ static void cpu_pre_save(void *opaque) PowerPCCPU *cpu = opaque; CPUPPCState *env = &cpu->env; int i; + uint64_t insns_compat_mask = + PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB + | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES + | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | PPC_FLOAT_FRSQRTES + | PPC_FLOAT_STFIWX | PPC_FLOAT_EXT + | PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ + | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC + | PPC_64B | PPC_64BX | PPC_ALTIVEC + | PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD; + uint64_t insns_compat_mask2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX + | PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 + | PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 + | PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 + | PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 + | PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | PPC2_TM; env->spr[SPR_LR] = env->lr; env->spr[SPR_CTR] = env->ctr; @@ -161,6 +176,12 @@ static void cpu_pre_save(void *opaque) env->spr[SPR_IBAT4U + 2*i] = env->IBAT[0][i+4]; env->spr[SPR_IBAT4U + 2*i + 1] = env->IBAT[1][i+4]; } + + /* Hacks for migration compatibility between 2.6, 2.7 & 2.8 */ + cpu->mig_msr_mask = env->msr_mask; + cpu->mig_insns_flags = env->insns_flags & insns_compat_mask; + cpu->mig_insns_flags2 = env->insns_flags2 & insns_compat_mask2; + cpu->mig_nb_BATs = env->nb_BATs; } static int cpu_post_load(void *opaque, int version_id) @@ -561,10 +582,10 @@ const VMStateDescription vmstate_ppc_cpu = { /* FIXME: access_type? */ /* Sanity checking */ - VMSTATE_UINTTL_EQUAL(env.msr_mask, PowerPCCPU), - VMSTATE_UINT64_EQUAL(env.insns_flags, PowerPCCPU), - VMSTATE_UINT64_EQUAL(env.insns_flags2, PowerPCCPU), - VMSTATE_UINT32_EQUAL(env.nb_BATs, PowerPCCPU), + VMSTATE_UINTTL(mig_msr_mask, PowerPCCPU), + VMSTATE_UINT64(mig_insns_flags, PowerPCCPU), + VMSTATE_UINT64(mig_insns_flags2, PowerPCCPU), + VMSTATE_UINT32(mig_nb_BATs, PowerPCCPU), VMSTATE_END_OF_LIST() }, .subsections = (const VMStateDescription*[]) {
When migration for target-ppc was converted to vmstate, several VMSTATE_EQUAL() checks were foolishly included of things that really should be internal state. Specifically we verified equality of the insns_flags and insns_flags2 fields, which are used within TCG to determine which groups of instructions are available on this cpu model. Between qemu-2.6 and qemu-2.7 we made some changes to these classes which broke migration. This path fixes migration both forwards and backwards. On migration from 2.6 to later versions we import the fields into teporary variables, which we then ignore. In migration backwards, we populate the temporary fields from the runtime fields, but mask out the bits which were added after qemu-2.6, allowing the VMSTATE_EQUAL in qemu-2.6 to accept the stream. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- target-ppc/cpu.h | 6 ++++++ target-ppc/machine.c | 29 +++++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-)