Skip to content

Commit

Permalink
target/arm: Implement v8M MSPLIM and PSPLIM registers
Browse files Browse the repository at this point in the history
The v8M architecture includes hardware support for enforcing
stack pointer limits. We don't implement this behaviour yet,
but provide the MSPLIM and PSPLIM stack pointer limit registers
as reads-as-written, so that when we do implement the checks
in future this won't break guest migration.

Signed-off-by: Peter Maydell <[email protected]>
Reviewed-by: Richard Henderson <[email protected]>
Message-id: [email protected]
  • Loading branch information
pm215 committed Feb 15, 2018
1 parent e1e7cbc commit 57bb315
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 0 deletions.
2 changes: 2 additions & 0 deletions target/arm/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,8 @@ typedef struct CPUARMState {
uint32_t secure; /* Is CPU in Secure state? (not guest visible) */
uint32_t csselr[M_REG_NUM_BANKS];
uint32_t scr[M_REG_NUM_BANKS];
uint32_t msplim[M_REG_NUM_BANKS];
uint32_t psplim[M_REG_NUM_BANKS];
} v7m;

/* Information associated with an exception about to be taken:
Expand Down
46 changes: 46 additions & 0 deletions target/arm/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -10403,6 +10403,16 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
return 0;
}
return env->v7m.other_ss_psp;
case 0x8a: /* MSPLIM_NS */
if (!env->v7m.secure) {
return 0;
}
return env->v7m.msplim[M_REG_NS];
case 0x8b: /* PSPLIM_NS */
if (!env->v7m.secure) {
return 0;
}
return env->v7m.psplim[M_REG_NS];
case 0x90: /* PRIMASK_NS */
if (!env->v7m.secure) {
return 0;
Expand Down Expand Up @@ -10444,6 +10454,16 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
return v7m_using_psp(env) ? env->v7m.other_sp : env->regs[13];
case 9: /* PSP */
return v7m_using_psp(env) ? env->regs[13] : env->v7m.other_sp;
case 10: /* MSPLIM */
if (!arm_feature(env, ARM_FEATURE_V8)) {
goto bad_reg;
}
return env->v7m.msplim[env->v7m.secure];
case 11: /* PSPLIM */
if (!arm_feature(env, ARM_FEATURE_V8)) {
goto bad_reg;
}
return env->v7m.psplim[env->v7m.secure];
case 16: /* PRIMASK */
return env->v7m.primask[env->v7m.secure];
case 17: /* BASEPRI */
Expand All @@ -10452,6 +10472,7 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
case 19: /* FAULTMASK */
return env->v7m.faultmask[env->v7m.secure];
default:
bad_reg:
qemu_log_mask(LOG_GUEST_ERROR, "Attempt to read unknown special"
" register %d\n", reg);
return 0;
Expand Down Expand Up @@ -10489,6 +10510,18 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
}
env->v7m.other_ss_psp = val;
return;
case 0x8a: /* MSPLIM_NS */
if (!env->v7m.secure) {
return;
}
env->v7m.msplim[M_REG_NS] = val & ~7;
return;
case 0x8b: /* PSPLIM_NS */
if (!env->v7m.secure) {
return;
}
env->v7m.psplim[M_REG_NS] = val & ~7;
return;
case 0x90: /* PRIMASK_NS */
if (!env->v7m.secure) {
return;
Expand Down Expand Up @@ -10568,6 +10601,18 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
env->v7m.other_sp = val;
}
break;
case 10: /* MSPLIM */
if (!arm_feature(env, ARM_FEATURE_V8)) {
goto bad_reg;
}
env->v7m.msplim[env->v7m.secure] = val & ~7;
break;
case 11: /* PSPLIM */
if (!arm_feature(env, ARM_FEATURE_V8)) {
goto bad_reg;
}
env->v7m.psplim[env->v7m.secure] = val & ~7;
break;
case 16: /* PRIMASK */
env->v7m.primask[env->v7m.secure] = val & 1;
break;
Expand Down Expand Up @@ -10600,6 +10645,7 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
env->v7m.control[env->v7m.secure] |= val & R_V7M_CONTROL_NPRIV_MASK;
break;
default:
bad_reg:
qemu_log_mask(LOG_GUEST_ERROR, "Attempt to write unknown special"
" register %d\n", reg);
return;
Expand Down
21 changes: 21 additions & 0 deletions target/arm/machine.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,26 @@ static const VMStateDescription vmstate_m_other_sp = {
}
};

static bool m_v8m_needed(void *opaque)
{
ARMCPU *cpu = opaque;
CPUARMState *env = &cpu->env;

return arm_feature(env, ARM_FEATURE_M) && arm_feature(env, ARM_FEATURE_V8);
}

static const VMStateDescription vmstate_m_v8m = {
.name = "cpu/m/v8m",
.version_id = 1,
.minimum_version_id = 1,
.needed = m_v8m_needed,
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(env.v7m.msplim, ARMCPU, M_REG_NUM_BANKS),
VMSTATE_UINT32_ARRAY(env.v7m.psplim, ARMCPU, M_REG_NUM_BANKS),
VMSTATE_END_OF_LIST()
}
};

static const VMStateDescription vmstate_m = {
.name = "cpu/m",
.version_id = 4,
Expand All @@ -270,6 +290,7 @@ static const VMStateDescription vmstate_m = {
&vmstate_m_csselr,
&vmstate_m_scr,
&vmstate_m_other_sp,
&vmstate_m_v8m,
NULL
}
};
Expand Down

0 comments on commit 57bb315

Please sign in to comment.