From 6713884243d72bdbddfbc303b9bca871a88d99a3 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 5 Mar 2018 13:09:21 -0500 Subject: [PATCH] target/arm: Handle SPSEL and current stack being out of sync in MSP/PSP reads For v8M it is possible for the CONTROL.SPSEL bit value and the current stack to be out of sync. This means we need to update the checks used in reads and writes of the PSP and MSP special registers to use v7m_using_psp() rather than directly checking the SPSEL bit in the control register. Backports commit 1169d3aa5b19adca9384d954d80e1f48da388284 from qemu --- qemu/target/arm/helper.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/qemu/target/arm/helper.c b/qemu/target/arm/helper.c index cc2bd3b4..f677d846 100644 --- a/qemu/target/arm/helper.c +++ b/qemu/target/arm/helper.c @@ -9142,11 +9142,9 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg) switch (reg) { case 8: /* MSP */ - return (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) ? - env->v7m.other_sp : env->regs[13]; + return v7m_using_psp(env) ? env->v7m.other_sp : env->regs[13]; case 9: /* PSP */ - return (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) ? - env->regs[13] : env->v7m.other_sp; + return v7m_using_psp(env) ? env->regs[13] : env->v7m.other_sp; case 16: /* PRIMASK */ return env->v7m.primask[env->v7m.secure]; case 17: /* BASEPRI */ @@ -9256,14 +9254,14 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val) } break; case 8: /* MSP */ - if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) { + if (v7m_using_psp(env)) { env->v7m.other_sp = val; } else { env->regs[13] = val; } break; case 9: /* PSP */ - if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) { + if (v7m_using_psp(env)) { env->regs[13] = val; } else { env->v7m.other_sp = val;