@samitouri / QOSamiQemu / commits / 84b9a537d6

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 {