On Mon, Jan 19, 2015 at 9:17 AM, Peter Maydell <peter.mayd...@linaro.org> wrote:
> We currently mark ARM coprocessor/system register definitions with > the flag ARM_CP_NO_MIGRATE for two different reasons: > 1) register is an alias on to state that's also visible via > some other register, and that other register is the one > responsible for migrating the state > 2) register is not actually state at all (for instance the TLB > or cache maintenance operation "registers") and it makes no > sense to attempt to migrate it or otherwise access the raw state > > This works fine for identifying which registers should be ignored > when performing migration, but we also use the same functions for > synchronizing system register state between QEMU and the kernel > when using KVM. In this case we don't want to try to sync state > into registers in category 2, but we do want to sync into registers > in category 1, because the kernel might have picked a different > one of the aliases as its choice for which one to expose for > migration. (In particular, on 32 bit hosts the kernel will > expose the state in the AArch32 version of the register, but > TCG's convention is to mark the AArch64 version as the version > to migrate, even if the CPU being emulated happens to be 32 bit, > so almost all system registers will hit this issue now that we've > added AArch64 system emulation.) > > Fix this by splitting the NO_MIGRATE flag in two (ALIAS and NO_RAW) > corresponding to the two different reasons we might not want to > migrate a register. When setting up the TCG list of registers to > migrate we honour both flags; when populating the list from KVM, > only ignore registers which are NO_RAW. > > Signed-off-by: Peter Maydell <peter.mayd...@linaro.org> > --- > target-arm/cpu.h | 15 +++- > target-arm/helper.c | 206 > ++++++++++++++++++++++++++-------------------------- > 2 files changed, 115 insertions(+), 106 deletions(-) > > diff --git a/target-arm/cpu.h b/target-arm/cpu.h > index 7ba55f0..831a841 100644 > --- a/target-arm/cpu.h > +++ b/target-arm/cpu.h > @@ -1112,8 +1112,14 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t > cpregid) > * a register definition to override a previous definition for the > * same (cp, is64, crn, crm, opc1, opc2) tuple: either the new or the > * old must have the OVERRIDE bit set. > - * NO_MIGRATE indicates that this register should be ignored for > migration; > - * (eg because any state is accessed via some other coprocessor register). > + * ALIAS indicates that this register is an alias view of some underlying > + * state which is also visible via another register, and that the other > + * register is handling migration; registers marked ALIAS will not be > migrated > + * but may have their state set by syncing of register state from KVM. > + * NO_RAW indicates that this register has no underlying state and does > not > + * support raw access for state saving/loading; it will not be used for > either > + * migration or KVM state synchronization. (Typically this is for > "registers" > + * which are actually used as instructions for cache maintenance and so > on.) > * IO indicates that this register does I/O and therefore its accesses > * need to be surrounded by gen_io_start()/gen_io_end(). In particular, > * registers which implement clocks or timers require this. > @@ -1123,8 +1129,9 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t > cpregid) > #define ARM_CP_64BIT 4 > #define ARM_CP_SUPPRESS_TB_END 8 > #define ARM_CP_OVERRIDE 16 > -#define ARM_CP_NO_MIGRATE 32 > +#define ARM_CP_ALIAS 32 > #define ARM_CP_IO 64 > +#define ARM_CP_NO_RAW 128 > #define ARM_CP_NOP (ARM_CP_SPECIAL | (1 << 8)) > #define ARM_CP_WFI (ARM_CP_SPECIAL | (2 << 8)) > #define ARM_CP_NZCV (ARM_CP_SPECIAL | (3 << 8)) > @@ -1134,7 +1141,7 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t > cpregid) > /* Used only as a terminator for ARMCPRegInfo lists */ > #define ARM_CP_SENTINEL 0xffff > /* Mask of only the flag bits in a type field */ > -#define ARM_CP_FLAG_MASK 0x7f > +#define ARM_CP_FLAG_MASK 0xff > > /* Valid values for ARMCPRegInfo state field, indicating which of > * the AArch32 and AArch64 execution states this register is visible in. > diff --git a/target-arm/helper.c b/target-arm/helper.c > index 1a5e067..18f04b2 100644 > --- a/target-arm/helper.c > +++ b/target-arm/helper.c > @@ -189,7 +189,7 @@ bool write_cpustate_to_list(ARMCPU *cpu) > ok = false; > continue; > } > - if (ri->type & ARM_CP_NO_MIGRATE) { > + if (ri->type & ARM_CP_NO_RAW) { > continue; > } > cpu->cpreg_values[i] = read_raw_cp_reg(&cpu->env, ri); > @@ -212,7 +212,7 @@ bool write_list_to_cpustate(ARMCPU *cpu) > ok = false; > continue; > } > - if (ri->type & ARM_CP_NO_MIGRATE) { > + if (ri->type & ARM_CP_NO_RAW) { > continue; > } > /* Write value and confirm it reads back as written > @@ -236,7 +236,7 @@ static void add_cpreg_to_list(gpointer key, gpointer > opaque) > regidx = *(uint32_t *)key; > ri = get_arm_cp_reginfo(cpu->cp_regs, regidx); > > - if (!(ri->type & ARM_CP_NO_MIGRATE)) { > + if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) { > cpu->cpreg_indexes[cpu->cpreg_array_len] = > cpreg_to_kvm_id(regidx); > /* The value array need not be initialized at this point */ > cpu->cpreg_array_len++; > @@ -252,7 +252,7 @@ static void count_cpreg(gpointer key, gpointer opaque) > regidx = *(uint32_t *)key; > ri = get_arm_cp_reginfo(cpu->cp_regs, regidx); > > - if (!(ri->type & ARM_CP_NO_MIGRATE)) { > + if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) { > cpu->cpreg_array_len++; > } > } > @@ -508,7 +508,7 @@ static const ARMCPRegInfo not_v7_cp_reginfo[] = { > .resetvalue = 0 }, > /* v6 doesn't have the cache ID registers but Linux reads them anyway > */ > { .name = "DUMMY", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = > CP_ANY, > - .access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_MIGRATE, > + .access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW, > .resetvalue = 0 }, > /* We don't implement pre-v7 debug but most CPUs had at least a > DBGDIDR; > * implementing it as RAZ means the "debug architecture version" bits > @@ -522,16 +522,16 @@ static const ARMCPRegInfo not_v7_cp_reginfo[] = { > */ > { .name = "TLBIALL", .cp = 15, .crn = 8, .crm = CP_ANY, > .opc1 = CP_ANY, .opc2 = 0, .access = PL1_W, .writefn = > tlbiall_write, > - .type = ARM_CP_NO_MIGRATE }, > + .type = ARM_CP_NO_RAW }, > { .name = "TLBIMVA", .cp = 15, .crn = 8, .crm = CP_ANY, > .opc1 = CP_ANY, .opc2 = 1, .access = PL1_W, .writefn = > tlbimva_write, > - .type = ARM_CP_NO_MIGRATE }, > + .type = ARM_CP_NO_RAW }, > { .name = "TLBIASID", .cp = 15, .crn = 8, .crm = CP_ANY, > .opc1 = CP_ANY, .opc2 = 2, .access = PL1_W, .writefn = > tlbiasid_write, > - .type = ARM_CP_NO_MIGRATE }, > + .type = ARM_CP_NO_RAW }, > { .name = "TLBIMVAA", .cp = 15, .crn = 8, .crm = CP_ANY, > .opc1 = CP_ANY, .opc2 = 3, .access = PL1_W, .writefn = > tlbimvaa_write, > - .type = ARM_CP_NO_MIGRATE }, > + .type = ARM_CP_NO_RAW }, > REGINFO_SENTINEL > }; > > @@ -854,7 +854,7 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { > * or PL0_RO as appropriate and then check PMUSERENR in the helper fn. > */ > { .name = "PMCNTENSET", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, > .opc2 = 1, > - .access = PL0_RW, .type = ARM_CP_NO_MIGRATE, > + .access = PL0_RW, .type = ARM_CP_ALIAS, > .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcnten), > .writefn = pmcntenset_write, > .accessfn = pmreg_access, > @@ -869,11 +869,11 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { > .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcnten), > .accessfn = pmreg_access, > .writefn = pmcntenclr_write, > - .type = ARM_CP_NO_MIGRATE }, > + .type = ARM_CP_ALIAS }, > { .name = "PMCNTENCLR_EL0", .state = ARM_CP_STATE_AA64, > .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 2, > .access = PL0_RW, .accessfn = pmreg_access, > - .type = ARM_CP_NO_MIGRATE, > + .type = ARM_CP_ALIAS, > .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten), > .writefn = pmcntenclr_write }, > { .name = "PMOVSR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = > 3, > @@ -928,7 +928,7 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { > .resetvalue = 0, > .writefn = pmintenset_write, .raw_writefn = raw_write }, > { .name = "PMINTENCLR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, > .opc2 = 2, > - .access = PL1_RW, .type = ARM_CP_NO_MIGRATE, > + .access = PL1_RW, .type = ARM_CP_ALIAS, > .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), > .resetvalue = 0, .writefn = pmintenclr_write, }, > { .name = "VBAR", .state = ARM_CP_STATE_BOTH, > @@ -939,7 +939,7 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { > .resetvalue = 0 }, > { .name = "CCSIDR", .state = ARM_CP_STATE_BOTH, > .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0, > - .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_MIGRATE }, > + .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_RAW }, > { .name = "CSSELR", .state = ARM_CP_STATE_BOTH, > .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0, > .access = PL1_RW, .writefn = csselr_write, .resetvalue = 0, > @@ -988,44 +988,44 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { > .resetfn = arm_cp_reset_ignore }, > { .name = "ISR_EL1", .state = ARM_CP_STATE_BOTH, > .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 1, .opc2 = 0, > - .type = ARM_CP_NO_MIGRATE, .access = PL1_R, .readfn = isr_read }, > + .type = ARM_CP_NO_RAW, .access = PL1_R, .readfn = isr_read }, > /* 32 bit ITLB invalidates */ > { .name = "ITLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 > = 0, > - .type = ARM_CP_NO_MIGRATE, .access = PL1_W, .writefn = > tlbiall_write }, > + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write }, > { .name = "ITLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 > = 1, > - .type = ARM_CP_NO_MIGRATE, .access = PL1_W, .writefn = > tlbimva_write }, > + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write }, > { .name = "ITLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 > = 2, > - .type = ARM_CP_NO_MIGRATE, .access = PL1_W, .writefn = > tlbiasid_write }, > + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write }, > /* 32 bit DTLB invalidates */ > { .name = "DTLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 > = 0, > - .type = ARM_CP_NO_MIGRATE, .access = PL1_W, .writefn = > tlbiall_write }, > + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write }, > { .name = "DTLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 > = 1, > - .type = ARM_CP_NO_MIGRATE, .access = PL1_W, .writefn = > tlbimva_write }, > + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write }, > { .name = "DTLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 > = 2, > - .type = ARM_CP_NO_MIGRATE, .access = PL1_W, .writefn = > tlbiasid_write }, > + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write }, > /* 32 bit TLB invalidates */ > { .name = "TLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = > 0, > - .type = ARM_CP_NO_MIGRATE, .access = PL1_W, .writefn = > tlbiall_write }, > + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write }, > { .name = "TLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = > 1, > - .type = ARM_CP_NO_MIGRATE, .access = PL1_W, .writefn = > tlbimva_write }, > + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write }, > { .name = "TLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 > = 2, > - .type = ARM_CP_NO_MIGRATE, .access = PL1_W, .writefn = > tlbiasid_write }, > + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write }, > { .name = "TLBIMVAA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 > = 3, > - .type = ARM_CP_NO_MIGRATE, .access = PL1_W, .writefn = > tlbimvaa_write }, > + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write }, > REGINFO_SENTINEL > }; > > static const ARMCPRegInfo v7mp_cp_reginfo[] = { > /* 32 bit TLB invalidates, Inner Shareable */ > { .name = "TLBIALLIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 > = 0, > - .type = ARM_CP_NO_MIGRATE, .access = PL1_W, .writefn = > tlbiall_is_write }, > + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_is_write > }, > { .name = "TLBIMVAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 > = 1, > - .type = ARM_CP_NO_MIGRATE, .access = PL1_W, .writefn = > tlbimva_is_write }, > + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_is_write > }, > { .name = "TLBIASIDIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, > .opc2 = 2, > - .type = ARM_CP_NO_MIGRATE, .access = PL1_W, > + .type = ARM_CP_NO_RAW, .access = PL1_W, > .writefn = tlbiasid_is_write }, > { .name = "TLBIMVAAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, > .opc2 = 3, > - .type = ARM_CP_NO_MIGRATE, .access = PL1_W, > + .type = ARM_CP_NO_RAW, .access = PL1_W, > .writefn = tlbimvaa_is_write }, > REGINFO_SENTINEL > }; > @@ -1268,7 +1268,7 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] > = { > * Our reset value matches the fixed frequency we implement the timer > at. > */ > { .name = "CNTFRQ", .cp = 15, .crn = 14, .crm = 0, .opc1 = 0, .opc2 = > 0, > - .type = ARM_CP_NO_MIGRATE, > + .type = ARM_CP_ALIAS, > .access = PL1_RW | PL0_R, .accessfn = gt_cntfrq_access, > .fieldoffset = offsetoflow32(CPUARMState, cp15.c14_cntfrq), > .resetfn = arm_cp_reset_ignore, > @@ -1288,7 +1288,7 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] > = { > }, > /* per-timer control */ > { .name = "CNTP_CTL", .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 > = 1, > - .type = ARM_CP_IO | ARM_CP_NO_MIGRATE, .access = PL1_RW | PL0_R, > + .type = ARM_CP_IO | ARM_CP_ALIAS, .access = PL1_RW | PL0_R, > .accessfn = gt_ptimer_access, > .fieldoffset = offsetoflow32(CPUARMState, > cp15.c14_timer[GTIMER_PHYS].ctl), > @@ -1304,7 +1304,7 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] > = { > .writefn = gt_ctl_write, .raw_writefn = raw_write, > }, > { .name = "CNTV_CTL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 > = 1, > - .type = ARM_CP_IO | ARM_CP_NO_MIGRATE, .access = PL1_RW | PL0_R, > + .type = ARM_CP_IO | ARM_CP_ALIAS, .access = PL1_RW | PL0_R, > .accessfn = gt_vtimer_access, > .fieldoffset = offsetoflow32(CPUARMState, > cp15.c14_timer[GTIMER_VIRT].ctl), > @@ -1321,52 +1321,52 @@ static const ARMCPRegInfo > generic_timer_cp_reginfo[] = { > }, > /* TimerValue views: a 32 bit downcounting view of the underlying > state */ > { .name = "CNTP_TVAL", .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, > .opc2 = 0, > - .type = ARM_CP_NO_MIGRATE | ARM_CP_IO, .access = PL1_RW | PL0_R, > + .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW | PL0_R, > .accessfn = gt_ptimer_access, > .readfn = gt_tval_read, .writefn = gt_tval_write, > }, > { .name = "CNTP_TVAL_EL0", .state = ARM_CP_STATE_AA64, > .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 0, > - .type = ARM_CP_NO_MIGRATE | ARM_CP_IO, .access = PL1_RW | PL0_R, > + .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW | PL0_R, > .readfn = gt_tval_read, .writefn = gt_tval_write, > }, > { .name = "CNTV_TVAL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, > .opc2 = 0, > - .type = ARM_CP_NO_MIGRATE | ARM_CP_IO, .access = PL1_RW | PL0_R, > + .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW | PL0_R, > .accessfn = gt_vtimer_access, > .readfn = gt_tval_read, .writefn = gt_tval_write, > }, > { .name = "CNTV_TVAL_EL0", .state = ARM_CP_STATE_AA64, > .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 0, > - .type = ARM_CP_NO_MIGRATE | ARM_CP_IO, .access = PL1_RW | PL0_R, > + .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW | PL0_R, > .readfn = gt_tval_read, .writefn = gt_tval_write, > }, > /* The counter itself */ > { .name = "CNTPCT", .cp = 15, .crm = 14, .opc1 = 0, > - .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE | > ARM_CP_IO, > + .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_RAW | ARM_CP_IO, > .accessfn = gt_pct_access, > .readfn = gt_cnt_read, .resetfn = arm_cp_reset_ignore, > }, > { .name = "CNTPCT_EL0", .state = ARM_CP_STATE_AA64, > .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 1, > - .access = PL0_R, .type = ARM_CP_NO_MIGRATE | ARM_CP_IO, > + .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO, > .accessfn = gt_pct_access, > .readfn = gt_cnt_read, .resetfn = gt_cnt_reset, > }, > { .name = "CNTVCT", .cp = 15, .crm = 14, .opc1 = 1, > - .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE | > ARM_CP_IO, > + .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_RAW | ARM_CP_IO, > .accessfn = gt_vct_access, > .readfn = gt_cnt_read, .resetfn = arm_cp_reset_ignore, > }, > { .name = "CNTVCT_EL0", .state = ARM_CP_STATE_AA64, > .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 2, > - .access = PL0_R, .type = ARM_CP_NO_MIGRATE | ARM_CP_IO, > + .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO, > .accessfn = gt_vct_access, > .readfn = gt_cnt_read, .resetfn = gt_cnt_reset, > }, > /* Comparison value, indicating when the timer goes off */ > { .name = "CNTP_CVAL", .cp = 15, .crm = 14, .opc1 = 2, > .access = PL1_RW | PL0_R, > - .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_NO_MIGRATE, > + .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_ALIAS, > .fieldoffset = offsetof(CPUARMState, > cp15.c14_timer[GTIMER_PHYS].cval), > .accessfn = gt_ptimer_access, .resetfn = arm_cp_reset_ignore, > .writefn = gt_cval_write, .raw_writefn = raw_write, > @@ -1381,7 +1381,7 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] > = { > }, > { .name = "CNTV_CVAL", .cp = 15, .crm = 14, .opc1 = 3, > .access = PL1_RW | PL0_R, > - .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_NO_MIGRATE, > + .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_ALIAS, > .fieldoffset = offsetof(CPUARMState, > cp15.c14_timer[GTIMER_VIRT].cval), > .accessfn = gt_vtimer_access, .resetfn = arm_cp_reset_ignore, > .writefn = gt_cval_write, .raw_writefn = raw_write, > @@ -1428,7 +1428,7 @@ static CPAccessResult ats_access(CPUARMState *env, > const ARMCPRegInfo *ri) > /* Other states are only available with TrustZone; in > * a non-TZ implementation these registers don't exist > * at all, which is an Uncategorized trap. This underdecoding > - * is safe because the reginfo is NO_MIGRATE. > + * is safe because the reginfo is NO_RAW. > */ > return CP_ACCESS_TRAP_UNCATEGORIZED; > } > @@ -1495,7 +1495,7 @@ static const ARMCPRegInfo vapa_cp_reginfo[] = { > #ifndef CONFIG_USER_ONLY > { .name = "ATS", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = > CP_ANY, > .access = PL1_W, .accessfn = ats_access, > - .writefn = ats_write, .type = ARM_CP_NO_MIGRATE }, > + .writefn = ats_write, .type = ARM_CP_NO_RAW }, > #endif > REGINFO_SENTINEL > }; > @@ -1554,12 +1554,12 @@ static uint64_t pmsav5_insn_ap_read(CPUARMState > *env, const ARMCPRegInfo *ri) > > static const ARMCPRegInfo pmsav5_cp_reginfo[] = { > { .name = "DATA_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = > 0, > - .access = PL1_RW, .type = ARM_CP_NO_MIGRATE, > + .access = PL1_RW, .type = ARM_CP_ALIAS, > .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_data_ap), > .resetvalue = 0, > .readfn = pmsav5_data_ap_read, .writefn = pmsav5_data_ap_write, }, > { .name = "INSN_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = > 1, > - .access = PL1_RW, .type = ARM_CP_NO_MIGRATE, > + .access = PL1_RW, .type = ARM_CP_ALIAS, > .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_insn_ap), > .resetvalue = 0, > .readfn = pmsav5_insn_ap_read, .writefn = pmsav5_insn_ap_write, }, > @@ -1691,7 +1691,7 @@ static void vmsa_ttbr_write(CPUARMState *env, const > ARMCPRegInfo *ri, > > static const ARMCPRegInfo vmsa_cp_reginfo[] = { > { .name = "DFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0, > - .access = PL1_RW, .type = ARM_CP_NO_MIGRATE, > + .access = PL1_RW, .type = ARM_CP_ALIAS, > .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dfsr_s), > offsetoflow32(CPUARMState, cp15.dfsr_ns) }, > .resetfn = arm_cp_reset_ignore, }, > @@ -1719,7 +1719,7 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = { > .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write, > .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[1]) }, > { .name = "TTBCR", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2, > - .access = PL1_RW, .type = ARM_CP_NO_MIGRATE, .writefn = > vmsa_ttbcr_write, > + .access = PL1_RW, .type = ARM_CP_ALIAS, .writefn = vmsa_ttbcr_write, > .resetfn = arm_cp_reset_ignore, .raw_writefn = vmsa_ttbcr_raw_write, > .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tcr_el[3]), > offsetoflow32(CPUARMState, cp15.tcr_el[1])} > }, > @@ -1789,7 +1789,7 @@ static const ARMCPRegInfo omap_cp_reginfo[] = { > .writefn = omap_threadid_write }, > { .name = "TI925T_STATUS", .cp = 15, .crn = 15, > .crm = 8, .opc1 = 0, .opc2 = 0, .access = PL1_RW, > - .type = ARM_CP_NO_MIGRATE, > + .type = ARM_CP_NO_RAW, > .readfn = arm_cp_read_zero, .writefn = omap_wfi_write, }, > /* TODO: Peripheral port remap register: > * On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt > controller > @@ -1798,7 +1798,7 @@ static const ARMCPRegInfo omap_cp_reginfo[] = { > */ > { .name = "OMAP_CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY, > .opc1 = 0, .opc2 = CP_ANY, .access = PL1_W, > - .type = ARM_CP_OVERRIDE | ARM_CP_NO_MIGRATE, > + .type = ARM_CP_OVERRIDE | ARM_CP_NO_RAW, > .writefn = omap_cachemaint_write }, > { .name = "C9", .cp = 15, .crn = 9, > .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, > @@ -1848,7 +1848,7 @@ static const ARMCPRegInfo dummy_c15_cp_reginfo[] = { > { .name = "C15_IMPDEF", .cp = 15, .crn = 15, > .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, > .access = PL1_RW, > - .type = ARM_CP_CONST | ARM_CP_NO_MIGRATE | ARM_CP_OVERRIDE, > + .type = ARM_CP_CONST | ARM_CP_NO_RAW | ARM_CP_OVERRIDE, > .resetvalue = 0 }, > REGINFO_SENTINEL > }; > @@ -1856,7 +1856,7 @@ static const ARMCPRegInfo dummy_c15_cp_reginfo[] = { > static const ARMCPRegInfo cache_dirty_status_cp_reginfo[] = { > /* Cache status: RAZ because we have no cache so it's always clean */ > { .name = "CDSR", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 6, > - .access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_MIGRATE, > + .access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW, > .resetvalue = 0 }, > REGINFO_SENTINEL > }; > @@ -1864,7 +1864,7 @@ static const ARMCPRegInfo > cache_dirty_status_cp_reginfo[] = { > static const ARMCPRegInfo cache_block_ops_cp_reginfo[] = { > /* We never have a a block transfer operation in progress */ > { .name = "BXSR", .cp = 15, .crn = 7, .crm = 12, .opc1 = 0, .opc2 = 4, > - .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_MIGRATE, > + .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW, > .resetvalue = 0 }, > /* The cache ops themselves: these all NOP for QEMU */ > { .name = "IICR", .cp = 15, .crm = 5, .opc1 = 0, > @@ -1887,10 +1887,10 @@ static const ARMCPRegInfo > cache_test_clean_cp_reginfo[] = { > * to indicate that there are no dirty cache lines. > */ > { .name = "TC_DCACHE", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, > .opc2 = 3, > - .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_MIGRATE, > + .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW, > .resetvalue = (1 << 30) }, > { .name = "TCI_DCACHE", .cp = 15, .crn = 7, .crm = 14, .opc1 = 0, > .opc2 = 3, > - .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_MIGRATE, > + .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW, > .resetvalue = (1 << 30) }, > REGINFO_SENTINEL > }; > @@ -1900,7 +1900,7 @@ static const ARMCPRegInfo strongarm_cp_reginfo[] = { > { .name = "C9_READBUFFER", .cp = 15, .crn = 9, > .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, > .access = PL1_RW, .resetvalue = 0, > - .type = ARM_CP_CONST | ARM_CP_OVERRIDE | ARM_CP_NO_MIGRATE }, > + .type = ARM_CP_CONST | ARM_CP_OVERRIDE | ARM_CP_NO_RAW }, > REGINFO_SENTINEL > }; > > @@ -1926,7 +1926,7 @@ static uint64_t mpidr_read(CPUARMState *env, const > ARMCPRegInfo *ri) > static const ARMCPRegInfo mpidr_cp_reginfo[] = { > { .name = "MPIDR", .state = ARM_CP_STATE_BOTH, > .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 5, > - .access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_MIGRATE }, > + .access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_RAW }, > REGINFO_SENTINEL > }; > > @@ -1947,12 +1947,12 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = { > .bank_fieldoffsets = { offsetof(CPUARMState, cp15.par_s), > offsetof(CPUARMState, cp15.par_ns)} }, > { .name = "TTBR0", .cp = 15, .crm = 2, .opc1 = 0, > - .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE, > + .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS, > .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s), > offsetof(CPUARMState, cp15.ttbr0_ns) }, > .writefn = vmsa_ttbr_write, .resetfn = arm_cp_reset_ignore }, > { .name = "TTBR1", .cp = 15, .crm = 2, .opc1 = 1, > - .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE, > + .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS, > .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s), > offsetof(CPUARMState, cp15.ttbr1_ns) }, > .writefn = vmsa_ttbr_write, .resetfn = arm_cp_reset_ignore }, > @@ -2144,7 +2144,7 @@ static const ARMCPRegInfo v8_cp_reginfo[] = { > .access = PL0_RW, .type = ARM_CP_NZCV }, > { .name = "DAIF", .state = ARM_CP_STATE_AA64, > .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 2, > - .type = ARM_CP_NO_MIGRATE, > + .type = ARM_CP_NO_RAW, > .access = PL0_RW, .accessfn = aa64_daif_access, > .fieldoffset = offsetof(CPUARMState, daif), > .writefn = aa64_daif_write, .resetfn = arm_cp_reset_ignore }, > @@ -2156,7 +2156,7 @@ static const ARMCPRegInfo v8_cp_reginfo[] = { > .access = PL0_RW, .readfn = aa64_fpsr_read, .writefn = > aa64_fpsr_write }, > { .name = "DCZID_EL0", .state = ARM_CP_STATE_AA64, > .opc0 = 3, .opc1 = 3, .opc2 = 7, .crn = 0, .crm = 0, > - .access = PL0_R, .type = ARM_CP_NO_MIGRATE, > + .access = PL0_R, .type = ARM_CP_NO_RAW, > .readfn = aa64_dczid_read }, > { .name = "DC_ZVA", .state = ARM_CP_STATE_AA64, > .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 4, .opc2 = 1, > @@ -2207,77 +2207,77 @@ static const ARMCPRegInfo v8_cp_reginfo[] = { > /* TLBI operations */ > { .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64, > .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0, > - .access = PL1_W, .type = ARM_CP_NO_MIGRATE, > + .access = PL1_W, .type = ARM_CP_NO_RAW, > .writefn = tlbiall_is_write }, > { .name = "TLBI_VAE1IS", .state = ARM_CP_STATE_AA64, > .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1, > - .access = PL1_W, .type = ARM_CP_NO_MIGRATE, > + .access = PL1_W, .type = ARM_CP_NO_RAW, > .writefn = tlbi_aa64_va_is_write }, > { .name = "TLBI_ASIDE1IS", .state = ARM_CP_STATE_AA64, > .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2, > - .access = PL1_W, .type = ARM_CP_NO_MIGRATE, > + .access = PL1_W, .type = ARM_CP_NO_RAW, > .writefn = tlbi_aa64_asid_is_write }, > { .name = "TLBI_VAAE1IS", .state = ARM_CP_STATE_AA64, > .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3, > - .access = PL1_W, .type = ARM_CP_NO_MIGRATE, > + .access = PL1_W, .type = ARM_CP_NO_RAW, > .writefn = tlbi_aa64_vaa_is_write }, > { .name = "TLBI_VALE1IS", .state = ARM_CP_STATE_AA64, > .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5, > - .access = PL1_W, .type = ARM_CP_NO_MIGRATE, > + .access = PL1_W, .type = ARM_CP_NO_RAW, > .writefn = tlbi_aa64_va_is_write }, > { .name = "TLBI_VAALE1IS", .state = ARM_CP_STATE_AA64, > .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7, > - .access = PL1_W, .type = ARM_CP_NO_MIGRATE, > + .access = PL1_W, .type = ARM_CP_NO_RAW, > .writefn = tlbi_aa64_vaa_is_write }, > { .name = "TLBI_VMALLE1", .state = ARM_CP_STATE_AA64, > .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0, > - .access = PL1_W, .type = ARM_CP_NO_MIGRATE, > + .access = PL1_W, .type = ARM_CP_NO_RAW, > .writefn = tlbiall_write }, > { .name = "TLBI_VAE1", .state = ARM_CP_STATE_AA64, > .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1, > - .access = PL1_W, .type = ARM_CP_NO_MIGRATE, > + .access = PL1_W, .type = ARM_CP_NO_RAW, > .writefn = tlbi_aa64_va_write }, > { .name = "TLBI_ASIDE1", .state = ARM_CP_STATE_AA64, > .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2, > - .access = PL1_W, .type = ARM_CP_NO_MIGRATE, > + .access = PL1_W, .type = ARM_CP_NO_RAW, > .writefn = tlbi_aa64_asid_write }, > { .name = "TLBI_VAAE1", .state = ARM_CP_STATE_AA64, > .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3, > - .access = PL1_W, .type = ARM_CP_NO_MIGRATE, > + .access = PL1_W, .type = ARM_CP_NO_RAW, > .writefn = tlbi_aa64_vaa_write }, > { .name = "TLBI_VALE1", .state = ARM_CP_STATE_AA64, > .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5, > - .access = PL1_W, .type = ARM_CP_NO_MIGRATE, > + .access = PL1_W, .type = ARM_CP_NO_RAW, > .writefn = tlbi_aa64_va_write }, > { .name = "TLBI_VAALE1", .state = ARM_CP_STATE_AA64, > .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7, > - .access = PL1_W, .type = ARM_CP_NO_MIGRATE, > + .access = PL1_W, .type = ARM_CP_NO_RAW, > .writefn = tlbi_aa64_vaa_write }, > #ifndef CONFIG_USER_ONLY > /* 64 bit address translation operations */ > { .name = "AT_S1E1R", .state = ARM_CP_STATE_AA64, > .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 0, > - .access = PL1_W, .type = ARM_CP_NO_MIGRATE, .writefn = ats_write }, > + .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write }, > { .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64, > .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 1, > - .access = PL1_W, .type = ARM_CP_NO_MIGRATE, .writefn = ats_write }, > + .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write }, > { .name = "AT_S1E0R", .state = ARM_CP_STATE_AA64, > .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 2, > - .access = PL1_W, .type = ARM_CP_NO_MIGRATE, .writefn = ats_write }, > + .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write }, > { .name = "AT_S1E0W", .state = ARM_CP_STATE_AA64, > .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 3, > - .access = PL1_W, .type = ARM_CP_NO_MIGRATE, .writefn = ats_write }, > + .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write }, > #endif > /* TLB invalidate last level of translation table walk */ > { .name = "TLBIMVALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, > .opc2 = 5, > - .type = ARM_CP_NO_MIGRATE, .access = PL1_W, .writefn = > tlbimva_is_write }, > + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_is_write > }, > { .name = "TLBIMVAALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, > .opc2 = 7, > - .type = ARM_CP_NO_MIGRATE, .access = PL1_W, > + .type = ARM_CP_NO_RAW, .access = PL1_W, > .writefn = tlbimvaa_is_write }, > { .name = "TLBIMVAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 > = 5, > - .type = ARM_CP_NO_MIGRATE, .access = PL1_W, .writefn = > tlbimva_write }, > + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write }, > { .name = "TLBIMVAAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 > = 7, > - .type = ARM_CP_NO_MIGRATE, .access = PL1_W, .writefn = > tlbimvaa_write }, > + .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write }, > /* 32 bit cache operations */ > { .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 > = 0, > .type = ARM_CP_NOP, .access = PL1_W }, > @@ -2312,12 +2312,12 @@ static const ARMCPRegInfo v8_cp_reginfo[] = { > .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s), > offsetoflow32(CPUARMState, cp15.dacr_ns) } }, > { .name = "ELR_EL1", .state = ARM_CP_STATE_AA64, > - .type = ARM_CP_NO_MIGRATE, > + .type = ARM_CP_ALIAS, > .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 1, > .access = PL1_RW, > .fieldoffset = offsetof(CPUARMState, elr_el[1]) }, > { .name = "SPSR_EL1", .state = ARM_CP_STATE_AA64, > - .type = ARM_CP_NO_MIGRATE, > + .type = ARM_CP_ALIAS, > .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 0, > .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, > banked_spsr[0]) }, > >From what I can tell, the SPSR and ELR regs are handled specially as I couldn't find the non-alias equivalents? If this is true it may be worth a comment. > /* We rely on the access checks not allowing the guest to write to the > @@ -2327,11 +2327,11 @@ static const ARMCPRegInfo v8_cp_reginfo[] = { > { .name = "SP_EL0", .state = ARM_CP_STATE_AA64, > .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 1, .opc2 = 0, > .access = PL1_RW, .accessfn = sp_el0_access, > - .type = ARM_CP_NO_MIGRATE, > + .type = ARM_CP_ALIAS, > .fieldoffset = offsetof(CPUARMState, sp_el[0]) }, > { .name = "SPSel", .state = ARM_CP_STATE_AA64, > .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 0, > - .type = ARM_CP_NO_MIGRATE, > + .type = ARM_CP_NO_RAW, > .access = PL1_RW, .readfn = spsel_read, .writefn = spsel_write }, > REGINFO_SENTINEL > }; > @@ -2343,7 +2343,7 @@ static const ARMCPRegInfo v8_el3_no_el2_cp_reginfo[] > = { > .access = PL2_RW, > .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore }, > { .name = "HCR_EL2", .state = ARM_CP_STATE_AA64, > - .type = ARM_CP_NO_MIGRATE, > + .type = ARM_CP_NO_RAW, > .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0, > .access = PL2_RW, > .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore }, > @@ -2386,12 +2386,12 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = { > .writefn = dacr_write, .raw_writefn = raw_write, > .fieldoffset = offsetof(CPUARMState, cp15.dacr32_el2) }, > { .name = "ELR_EL2", .state = ARM_CP_STATE_AA64, > - .type = ARM_CP_NO_MIGRATE, > + .type = ARM_CP_ALIAS, > .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1, > .access = PL2_RW, > .fieldoffset = offsetof(CPUARMState, elr_el[2]) }, > { .name = "ESR_EL2", .state = ARM_CP_STATE_AA64, > - .type = ARM_CP_NO_MIGRATE, > + .type = ARM_CP_ALIAS, > .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0, > .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, > cp15.esr_el[2]) }, > { .name = "IFSR32_EL2", .state = ARM_CP_STATE_AA64, > @@ -2402,7 +2402,7 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = { > .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0, > .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, > cp15.far_el[2]) }, > { .name = "SPSR_EL2", .state = ARM_CP_STATE_AA64, > - .type = ARM_CP_NO_MIGRATE, > + .type = ARM_CP_ALIAS, > .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0, > .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, > banked_spsr[6]) }, > { .name = "VBAR_EL2", .state = ARM_CP_STATE_AA64, > @@ -2418,7 +2418,7 @@ static const ARMCPRegInfo el3_cp_reginfo[] = { > .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0, > .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, > cp15.scr_el3), > .resetvalue = 0, .writefn = scr_write }, > - { .name = "SCR", .type = ARM_CP_NO_MIGRATE, > + { .name = "SCR", .type = ARM_CP_ALIAS, > .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 0, > .access = PL3_RW, .fieldoffset = offsetoflow32(CPUARMState, > cp15.scr_el3), > .resetfn = arm_cp_reset_ignore, .writefn = scr_write }, > @@ -2451,19 +2451,19 @@ static const ARMCPRegInfo el3_cp_reginfo[] = { > .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write, > .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[3]) }, > { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64, > - .type = ARM_CP_NO_MIGRATE, > + .type = ARM_CP_ALIAS, > .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 1, > .access = PL3_RW, > .fieldoffset = offsetof(CPUARMState, elr_el[3]) }, > { .name = "ESR_EL3", .state = ARM_CP_STATE_AA64, > - .type = ARM_CP_NO_MIGRATE, > + .type = ARM_CP_ALIAS, > .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 2, .opc2 = 0, > .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, > cp15.esr_el[3]) }, > { .name = "FAR_EL3", .state = ARM_CP_STATE_AA64, > .opc0 = 3, .opc1 = 6, .crn = 6, .crm = 0, .opc2 = 0, > .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, > cp15.far_el[3]) }, > { .name = "SPSR_EL3", .state = ARM_CP_STATE_AA64, > - .type = ARM_CP_NO_MIGRATE, > + .type = ARM_CP_ALIAS, > .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 0, > .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, > banked_spsr[7]) }, > { .name = "VBAR_EL3", .state = ARM_CP_STATE_AA64, > @@ -2510,7 +2510,7 @@ static const ARMCPRegInfo debug_cp_reginfo[] = { > */ > { .name = "MDCCSR_EL0", .state = ARM_CP_STATE_BOTH, > .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0, > - .type = ARM_CP_NO_MIGRATE, > + .type = ARM_CP_ALIAS, > .access = PL1_R, > .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), > .resetfn = arm_cp_reset_ignore }, > @@ -2963,7 +2963,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) > ARMCPRegInfo pmcr = { > .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, > .opc2 = 0, > .access = PL0_RW, > - .type = ARM_CP_IO | ARM_CP_NO_MIGRATE, > + .type = ARM_CP_IO | ARM_CP_ALIAS, > .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr), > .accessfn = pmreg_access, .writefn = pmcr_write, > .raw_writefn = raw_write, > @@ -3440,14 +3440,14 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, > const ARMCPRegInfo *r, > */ > if ((r->state == ARM_CP_STATE_BOTH && ns) || > (arm_feature(&cpu->env, ARM_FEATURE_V8) && !ns)) { > - r2->type |= ARM_CP_NO_MIGRATE; > + r2->type |= ARM_CP_ALIAS; > r2->resetfn = arm_cp_reset_ignore; > } > } else if ((secstate != r->secure) && !ns) { > /* The register is not banked so we only want to allow > migration of > * the non-secure instance. > */ > - r2->type |= ARM_CP_NO_MIGRATE; > + r2->type |= ARM_CP_ALIAS; > r2->resetfn = arm_cp_reset_ignore; > } > > @@ -3496,15 +3496,17 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, > const ARMCPRegInfo *r, > r2->opc2 = opc2; > /* By convention, for wildcarded registers only the first > * entry is used for migration; the others are marked as > - * NO_MIGRATE so we don't try to transfer the register > + * ALIAS so we don't try to transfer the register > * multiple times. Special registers (ie NOP/WFI) are > - * never migratable. > + * never migratable and not even raw-accessible. > */ > - if ((r->type & ARM_CP_SPECIAL) || > - ((r->crm == CP_ANY) && crm != 0) || > + if ((r->type & ARM_CP_SPECIAL)) { > + r2->type |= ARM_CP_NO_RAW; > + } > + if (((r->crm == CP_ANY) && crm != 0) || > ((r->opc1 == CP_ANY) && opc1 != 0) || > ((r->opc2 == CP_ANY) && opc2 != 0)) { > - r2->type |= ARM_CP_NO_MIGRATE; > + r2->type |= ARM_CP_ALIAS; > } > > /* Overriding of an existing definition must be explicitly > -- > 1.9.1 > > Otherwise, Reviewed-by: Greg Bellows <greg.bell...@linaro.org>