diff mbox

[v2] Undefine SWP instruction unless SCTLR.SW bit is set

Message ID CABtrw+ODvkBnqSg2wuWg5OzqtM+dfR8A4LXmxjLPLXkeyUTQ0w@mail.gmail.com
State New
Headers show

Commit Message

Alexey Starikovskiy April 17, 2012, 12:28 p.m. UTC
ARM v7MP deprecates use of SWP instruction and only defines it
if OS explicitly requests it via setting SCTLR.SW bit.
Such a request is expected to occur only once during OS init, thus
only static checking for this bit and flush of all translations
is done on SCTLR change.

Signed-off-by: Alexey Starikovskiy <aystarik@gmail.com>
---
 target-arm/helper.c    |    2 ++
 target-arm/translate.c |    9 +++++++++
 2 files changed, 11 insertions(+), 0 deletions(-)

Comments

Peter Maydell April 17, 2012, 12:37 p.m. UTC | #1
On 17 April 2012 13:28, Alexey Starikovskiy <aystarik@gmail.com> wrote:
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -7415,6 +7415,15 @@ static void disas_arm_insn(CPUARMState * env,
> DisasContext *s)
>                         }
>                         tcg_temp_free(addr);
>                     } else {
> +#ifndef CONFIG_USER_ONLY
> +                        if (arm_feature(env, ARM_FEATURE_V7MP) &&
> +                            !(env->cp15.c1_sys & (1 << 10))) {
> +                            /* Check if SCTLR.SW is set. Any change to SCTLR
> +                             * invalidates all translations, so we are safe.
> +                             */
> +                            goto illegal_op;
> +                        }
> +#endif

I'm OK with this as a fix for the user-mode issue, but it needs a comment
explaining why this code is only here in system mode.

-- PMM
diff mbox

Patch

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 28f127b..e8b17a4 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1491,6 +1491,8 @@  void HELPER(set_cp15)(CPUARMState *env, uint32_t
insn, uint32_t val)
             /* ??? Lots of these bits are not implemented.  */
             /* This may enable/disable the MMU, so do a TLB flush.  */
             tlb_flush(env, 1);
+            /* This may enable/disable SWP instruction, so do TB flush too */
+            tb_flush(env);
             break;
         case 1: /* Auxiliary control register.  */
             if (arm_feature(env, ARM_FEATURE_XSCALE)) {
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 7a3c7d6..452b300 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -7415,6 +7415,15 @@  static void disas_arm_insn(CPUARMState * env,
DisasContext *s)
                         }
                         tcg_temp_free(addr);
                     } else {
+#ifndef CONFIG_USER_ONLY
+                        if (arm_feature(env, ARM_FEATURE_V7MP) &&
+                            !(env->cp15.c1_sys & (1 << 10))) {
+                            /* Check if SCTLR.SW is set. Any change to SCTLR
+                             * invalidates all translations, so we are safe.
+                             */
+                            goto illegal_op;
+                        }
+#endif
                         /* SWP instruction */
                         rm = (insn) & 0xf;