diff mbox series

[1/7] target/arm: Handle SPSEL and current stack being out of sync in MSP/PSP reads

Message ID 1512153879-5291-2-git-send-email-peter.maydell@linaro.org
State New
Headers show
Series armv8m: Implement TT, and other bugfixes | expand

Commit Message

Peter Maydell Dec. 1, 2017, 6:44 p.m. UTC
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.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/helper.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

Comments

Richard Henderson Dec. 3, 2017, 2:58 p.m. UTC | #1
On 12/01/2017 10:44 AM, Peter Maydell wrote:
> 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.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/helper.c | 10 ++++------
>  1 file changed, 4 insertions(+), 6 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~
Philippe Mathieu-Daudé Dec. 5, 2017, 6:54 p.m. UTC | #2
On 12/01/2017 03:44 PM, Peter Maydell wrote:
> 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.

good catch.

> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> ---
>  target/arm/helper.c | 10 ++++------
>  1 file changed, 4 insertions(+), 6 deletions(-)
> 
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index 91a9300..88394d4 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -9953,11 +9953,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 */
> @@ -10059,14 +10057,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;
>
diff mbox series

Patch

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 91a9300..88394d4 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -9953,11 +9953,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 */
@@ -10059,14 +10057,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;