Fixes: 9831d3cab168 ("target/hexagon: Add privilege check, use tag_ignore()")
Reviewed-by: Pierrick Bouvier <[email protected]>
Signed-off-by: Brian Cain <[email protected]>
---
 target/hexagon/cpu.h            |  1 +
 target/hexagon/translate.h      |  1 +
 target/hexagon/cpu.c            |  2 ++
 target/hexagon/translate.c      | 15 +++++++++++++++
 target/hexagon/gen_tcg_funcs.py | 16 ++++++++++------
 5 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index 2da3b586b5a..c1a944920e8 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -226,6 +226,7 @@ static inline HexagonHVXContext *hex_hvx(CPUHexagonState 
*env)
 FIELD(TB_FLAGS, IS_TIGHT_LOOP, 0, 1)
 FIELD(TB_FLAGS, MMU_INDEX, 1, 3)
 FIELD(TB_FLAGS, HVX_COPROC_ENABLED, 5, 1)
+FIELD(TB_FLAGS, CPU_MODE, 6, 2)
 
 G_NORETURN void hexagon_raise_exception_err(CPUHexagonState *env,
                                             uint32_t exception,
diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index ccf9d52997a..dc0c6b18bf1 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -45,6 +45,7 @@ typedef struct DisasContext {
     DECLARE_BITMAP(gpr_uncond, TOTAL_PER_THREAD_REGS);
     bool implicit_usr_write;
 #ifndef CONFIG_USER_ONLY
+    uint32_t cpu_mode;
     int greg_log[GREG_WRITES_MAX];
     int greg_log_idx;
     DECLARE_BITMAP(gregs_written, NUM_GREGS);
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index 796bb6df9db..474c4b3c550 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -352,6 +352,8 @@ static TCGTBCPUState hexagon_get_tb_cpu_state(CPUState *cs)
     hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, HVX_COPROC_ENABLED,
                            cpu->hvx_ctx[0] &&
                            GET_SSR_FIELD(SSR_XE, env->t_sreg[HEX_SREG_SSR]));
+    hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, CPU_MODE,
+                           get_cpu_mode(env));
 #else
     hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, MMU_INDEX, MMU_USER_IDX);
 #endif
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index beee09bc4cb..e2a5038a1a5 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -1289,6 +1289,20 @@ static void decode_and_translate_packet(CPUHexagonState 
*env, DisasContext *ctx)
                                       HEX_CAUSE_REG_WRITE_CONFLICT);
             return;
         }
+#ifndef CONFIG_USER_ONLY
+        if (check_for_attrib(&ctx->pkt, A_PRIV) &&
+            ctx->cpu_mode != HEX_CPU_MODE_MONITOR) {
+            hex_gen_exception_end_tb(ctx, HEX_CAUSE_PRIV_USER_NO_SINSN);
+            ctx->base.pc_next += ctx->pkt.encod_pkt_size_in_bytes;
+            return;
+        }
+        if (check_for_attrib(&ctx->pkt, A_GUEST) &&
+            ctx->cpu_mode == HEX_CPU_MODE_USER) {
+            hex_gen_exception_end_tb(ctx, HEX_CAUSE_PRIV_USER_NO_GINSN);
+            ctx->base.pc_next += ctx->pkt.encod_pkt_size_in_bytes;
+            return;
+        }
+#endif
         gen_start_packet(ctx);
         for (i = 0; i < ctx->pkt.num_insns; i++) {
             ctx->insn = &ctx->pkt.insn[i];
@@ -1321,6 +1335,7 @@ static void 
hexagon_tr_init_disas_context(DisasContextBase *dcbase,
     ctx->hvx_coproc_enabled =
         FIELD_EX32(hex_flags, TB_FLAGS, HVX_COPROC_ENABLED);
     ctx->hvx_check_emitted = false;
+    ctx->cpu_mode = FIELD_EX32(hex_flags, TB_FLAGS, CPU_MODE);
 #endif
 }
 
diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
index b09ce7c285f..61effa38cfa 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -58,16 +58,20 @@ def gen_tcg_func(f, tag, regs, imms):
 
     f.write("    Insn *insn G_GNUC_UNUSED = ctx->insn;\n")
 
-    if "A_PRIV" in hex_common.attribdict[tag]:
+    if (
+        "A_PRIV" in hex_common.attribdict[tag]
+        or "A_GUEST" in hex_common.attribdict[tag]
+    ):
         f.write(dedent("""\
 #ifdef CONFIG_USER_ONLY
-    hex_gen_exception_end_tb(ctx, HEX_CAUSE_PRIV_USER_NO_SINSN);
-#else
 """))
-    if "A_GUEST" in hex_common.attribdict[tag]:
+        if "A_PRIV" in hex_common.attribdict[tag]:
+            f.write("    hex_gen_exception_end_tb(ctx, "
+                    "HEX_CAUSE_PRIV_USER_NO_SINSN);\n")
+        else:
+            f.write("    hex_gen_exception_end_tb(ctx, "
+                    "HEX_CAUSE_PRIV_USER_NO_GINSN);\n")
         f.write(dedent("""\
-#ifdef CONFIG_USER_ONLY
-    hex_gen_exception_end_tb(ctx, HEX_CAUSE_PRIV_USER_NO_GINSN);
 #else
 """))
     if hex_common.need_ea(tag):
-- 
2.34.1

Reply via email to