Commit 84b9a537d6 for qemu.org
commit 84b9a537d6d3c7d336d437701c28d9545f8c19fa
Author: Brian Cain <brian.cain@oss.qualcomm.com>
Date: Mon Jul 13 18:09:53 2026 -0700
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>
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 05c9aa0446..f48a27bc09 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -495,7 +495,7 @@ static inline void gen_store_conditional4(DisasContext *ctx,
zero = tcg_constant_tl(0);
tmp = tcg_temp_new();
tcg_gen_atomic_cmpxchg_tl(tmp, hex_llsc_addr, hex_llsc_val, src,
- ctx->mem_idx, MO_32);
+ ctx->mem_idx, MO_32 | MO_ALIGN);
tcg_gen_movcond_tl(TCG_COND_EQ, pred, tmp, hex_llsc_val,
one, zero);
tcg_gen_br(done);
@@ -520,7 +520,7 @@ static inline void gen_store_conditional8(DisasContext *ctx,
zero = tcg_constant_i64(0);
tmp = tcg_temp_new_i64();
tcg_gen_atomic_cmpxchg_i64(tmp, hex_llsc_addr, hex_llsc_val_i64, src,
- ctx->mem_idx, MO_64);
+ ctx->mem_idx, MO_64 | MO_ALIGN);
tcg_gen_movcond_i64(TCG_COND_EQ, tmp, tmp, hex_llsc_val_i64,
one, zero);
tcg_gen_extrl_i64_i32(pred, tmp);
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 125952aee5..3ce223caba 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -95,19 +95,26 @@ static void commit_store(CPUHexagonState *env, int slot_num, uintptr_t ra)
{
uint32_t width = env->mem_log_stores[slot_num].width;
target_ulong va = env->mem_log_stores[slot_num].va;
+ MemOpIdx oi;
switch (width) {
case 1:
cpu_stb_data_ra(env, va, env->mem_log_stores[slot_num].data32, ra);
break;
case 2:
- cpu_stw_le_data_ra(env, va, env->mem_log_stores[slot_num].data32, ra);
+ oi = make_memop_idx(MO_LEUW | MO_ALIGN,
+ cpu_mmu_index(env_cpu(env), false));
+ cpu_stw_mmu(env, va, env->mem_log_stores[slot_num].data32, oi, ra);
break;
case 4:
- cpu_stl_le_data_ra(env, va, env->mem_log_stores[slot_num].data32, ra);
+ oi = make_memop_idx(MO_LEUL | MO_ALIGN,
+ cpu_mmu_index(env_cpu(env), false));
+ cpu_stl_mmu(env, va, env->mem_log_stores[slot_num].data32, oi, ra);
break;
case 8:
- cpu_stq_le_data_ra(env, va, env->mem_log_stores[slot_num].data64, ra);
+ oi = make_memop_idx(MO_LEUQ | MO_ALIGN,
+ cpu_mmu_index(env_cpu(env), false));
+ cpu_stq_mmu(env, va, env->mem_log_stores[slot_num].data64, oi, ra);
break;
default:
g_assert_not_reached();
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 77235916f4..5d54ce8caa 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -896,17 +896,17 @@ void process_store(DisasContext *ctx, int slot_num)
case 2:
tcg_gen_qemu_st_tl(hex_store_val32[slot_num],
hex_store_addr[slot_num],
- ctx->mem_idx, MO_LE | MO_UW);
+ ctx->mem_idx, MO_LE | MO_UW | MO_ALIGN);
break;
case 4:
tcg_gen_qemu_st_tl(hex_store_val32[slot_num],
hex_store_addr[slot_num],
- ctx->mem_idx, MO_LE | MO_UL);
+ ctx->mem_idx, MO_LE | MO_UL | MO_ALIGN);
break;
case 8:
tcg_gen_qemu_st_i64(hex_store_val64[slot_num],
hex_store_addr[slot_num],
- ctx->mem_idx, MO_LE | MO_UQ);
+ ctx->mem_idx, MO_LE | MO_UQ | MO_ALIGN);
break;
default:
{