hexagon_get_tb_cpu_state() detects a misaligned PC and raises an exception, but it passed HEX_CAUSE_PC_NOT_ALIGNED (a cause code) as the event argument to hexagon_raise_exception_err(), whose second parameter is the event index (it ends up in cs->exception_index). This causes an infinite reboot loop when we reache a misaligned PC.
Similarly, gen_exception_decode_fail() is called with a cause code (HEX_CAUSE_INVALID_PACKET) but unconditionally routes it through gen_exception(), which treats its argument as an event index and stores it directly in cs->exception_index. Reviewed-by: Pierrick Bouvier <[email protected]> Signed-off-by: Matheus Tavares Bernardino <[email protected]> --- linux-user/hexagon/cpu_loop.c | 5 +---- target/hexagon/cpu.c | 3 ++- target/hexagon/translate.c | 4 ++++ 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c index d7f73439db..d46b922479 100644 --- a/linux-user/hexagon/cpu_loop.c +++ b/linux-user/hexagon/cpu_loop.c @@ -78,6 +78,7 @@ void cpu_loop(CPUHexagonState *env) break; case HEX_CAUSE_MISALIGNED_LOAD: case HEX_CAUSE_MISALIGNED_STORE: + case HEX_CAUSE_PC_NOT_ALIGNED: force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, env->gpr[HEX_REG_PC]); break; @@ -88,10 +89,6 @@ void cpu_loop(CPUHexagonState *env) exit(EXIT_FAILURE); } break; - case HEX_CAUSE_PC_NOT_ALIGNED: - force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, - env->gpr[HEX_REG_R31]); - break; case HEX_CAUSE_INVALID_PACKET: case HEX_CAUSE_REG_WRITE_CONFLICT: force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index 7067e5b70f..134fbb2cfa 100644 --- a/target/hexagon/cpu.c +++ b/target/hexagon/cpu.c @@ -323,7 +323,8 @@ static TCGTBCPUState hexagon_get_tb_cpu_state(CPUState *cs) hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP, 1); } if (pc & PCALIGN_MASK) { - hexagon_raise_exception_err(env, HEX_CAUSE_PC_NOT_ALIGNED, 0); + env->cause_code = HEX_CAUSE_PC_NOT_ALIGNED; + hexagon_raise_exception_err(env, HEX_EVENT_PRECISE, (uint32_t)pc); } #ifndef CONFIG_USER_ONLY diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c index 06a8159d28..29821ffe3d 100644 --- a/target/hexagon/translate.c +++ b/target/hexagon/translate.c @@ -245,7 +245,11 @@ static void gen_exception_decode_fail(DisasContext *ctx, int nwords, int excp) gen_exec_counters(ctx); tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], fail_pc); +#ifdef CONFIG_USER_ONLY gen_exception(excp, fail_pc); +#else + gen_precise_exception(excp, fail_pc); +#endif ctx->base.is_jmp = DISAS_NORETURN; ctx->base.pc_next = fail_pc; } -- 2.37.2
