target/hexagon: raise SIGBUS on unaligned scalar stores
hexagon-linux-user had no enforcement of alignment for scalar store exceptions, and unaligned stores silently succeeded instead of raising SIGBUS. Stores are logged rather than committed immediately, so both commit paths need the fix. Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> Reviewed-by: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Brian Cain committed
Jul 13, 2026 at 18:09 UTC
84b9a537d6d3c7d336d437701c28d9545f8c19fa
3 files changed
+15
-8
target/hexagon/genptr.c
+2
-2
@@ -495,7 +495,7 @@ static inline void gen_store_conditional4(DisasContext *ctx,
495
zero = tcg_constant_tl(0);
496
tmp = tcg_temp_new();
497
tcg_gen_atomic_cmpxchg_tl(tmp, hex_llsc_addr, hex_llsc_val, src,
498
- ctx->mem_idx, MO_32);
498
+ ctx->mem_idx, MO_32 | MO_ALIGN);
499
tcg_gen_movcond_tl(TCG_COND_EQ, pred, tmp, hex_llsc_val,
500
one, zero);
501
tcg_gen_br(done);
@@ -520,7 +520,7 @@ static inline void gen_store_conditional8(DisasContext *ctx,
520
zero = tcg_constant_i64(0);
521
tmp = tcg_temp_new_i64();
522
tcg_gen_atomic_cmpxchg_i64(tmp, hex_llsc_addr, hex_llsc_val_i64, src,
523
- ctx->mem_idx, MO_64);
523
+ ctx->mem_idx, MO_64 | MO_ALIGN);
524
tcg_gen_movcond_i64(TCG_COND_EQ, tmp, tmp, hex_llsc_val_i64,
525
one, zero);
526
tcg_gen_extrl_i64_i32(pred, tmp);
target/hexagon/op_helper.c
+10
-3
@@ -95,19 +95,26 @@ static void commit_store(CPUHexagonState *env, int slot_num, uintptr_t ra)
95
{
96
uint32_t width = env->mem_log_stores[slot_num].width;
97
target_ulong va = env->mem_log_stores[slot_num].va;
98
+ MemOpIdx oi;
99
100
switch (width) {
101
case 1:
102
cpu_stb_data_ra(env, va, env->mem_log_stores[slot_num].data32, ra);
103
break;
104
case 2:
104
- cpu_stw_le_data_ra(env, va, env->mem_log_stores[slot_num].data32, ra);
105
+ oi = make_memop_idx(MO_LEUW | MO_ALIGN,
106
+ cpu_mmu_index(env_cpu(env), false));
107
+ cpu_stw_mmu(env, va, env->mem_log_stores[slot_num].data32, oi, ra);
108
break;
109
case 4:
107
- cpu_stl_le_data_ra(env, va, env->mem_log_stores[slot_num].data32, ra);
110
+ oi = make_memop_idx(MO_LEUL | MO_ALIGN,
111
+ cpu_mmu_index(env_cpu(env), false));
112
+ cpu_stl_mmu(env, va, env->mem_log_stores[slot_num].data32, oi, ra);
113
break;
114
case 8:
110
- cpu_stq_le_data_ra(env, va, env->mem_log_stores[slot_num].data64, ra);
115
+ oi = make_memop_idx(MO_LEUQ | MO_ALIGN,
116
+ cpu_mmu_index(env_cpu(env), false));
117
+ cpu_stq_mmu(env, va, env->mem_log_stores[slot_num].data64, oi, ra);
118
break;
119
default:
120
g_assert_not_reached();
target/hexagon/translate.c
+3
-3
@@ -896,17 +896,17 @@ void process_store(DisasContext *ctx, int slot_num)
896
case 2:
897
tcg_gen_qemu_st_tl(hex_store_val32[slot_num],
898
hex_store_addr[slot_num],
899
- ctx->mem_idx, MO_LE | MO_UW);
899
+ ctx->mem_idx, MO_LE | MO_UW | MO_ALIGN);
900
break;
901
case 4:
902
tcg_gen_qemu_st_tl(hex_store_val32[slot_num],
903
hex_store_addr[slot_num],
904
- ctx->mem_idx, MO_LE | MO_UL);
904
+ ctx->mem_idx, MO_LE | MO_UL | MO_ALIGN);
905
break;
906
case 8:
907
tcg_gen_qemu_st_i64(hex_store_val64[slot_num],
908
hex_store_addr[slot_num],
909
- ctx->mem_idx, MO_LE | MO_UQ);
909
+ ctx->mem_idx, MO_LE | MO_UQ | MO_ALIGN);
910
break;
911
default:
912
{