Commit 93cf730514 for qemu.org
commit 93cf73051435c8695d7d0b04dbad4bb8d5339dd2
Author: Brian Cain <brian.cain@oss.qualcomm.com>
Date: Mon Jul 13 18:09:52 2026 -0700
target/hexagon: raise SIGBUS on unaligned scalar loads
hexagon-linux-user had no enforcement of alignment for scalar load
exceptions, and unaligned loads silently succeeded instead of raising
SIGBUS.
Add MO_ALIGN to the MEM_LOAD* macros, the locked-load and
load-frame helpers in genptr.c, and the idef-parser's fLOAD.
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 1ebc747140..05c9aa0446 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -470,14 +470,14 @@ void gen_set_byte_i64(int N, TCGv_i64 result, TCGv src)
static inline void gen_load_locked4u(TCGv dest, TCGv vaddr, int mem_index)
{
- tcg_gen_qemu_ld_tl(dest, vaddr, mem_index, MO_LE | MO_UL);
+ tcg_gen_qemu_ld_tl(dest, vaddr, mem_index, MO_LE | MO_UL | MO_ALIGN);
tcg_gen_mov_tl(hex_llsc_addr, vaddr);
tcg_gen_mov_tl(hex_llsc_val, dest);
}
static inline void gen_load_locked8u(TCGv_i64 dest, TCGv vaddr, int mem_index)
{
- tcg_gen_qemu_ld_i64(dest, vaddr, mem_index, MO_LE | MO_UQ);
+ tcg_gen_qemu_ld_i64(dest, vaddr, mem_index, MO_LE | MO_UQ | MO_ALIGN);
tcg_gen_mov_tl(hex_llsc_addr, vaddr);
tcg_gen_mov_i64(hex_llsc_val_i64, dest);
}
@@ -890,7 +890,7 @@ static void gen_load_frame(DisasContext *ctx, TCGv_i64 frame, TCGv EA)
{
Insn *insn = ctx->insn; /* Needed for CHECK_NOSHUF */
CHECK_NOSHUF(EA, 8);
- tcg_gen_qemu_ld_i64(frame, EA, ctx->mem_idx, MO_LE | MO_UQ);
+ tcg_gen_qemu_ld_i64(frame, EA, ctx->mem_idx, MO_LE | MO_UQ | MO_ALIGN);
}
/* Stack overflow check */
diff --git a/target/hexagon/idef-parser/parser-helpers.c b/target/hexagon/idef-parser/parser-helpers.c
index b942d9ea16..49cc11fddd 100644
--- a/target/hexagon/idef-parser/parser-helpers.c
+++ b/target/hexagon/idef-parser/parser-helpers.c
@@ -1770,7 +1770,7 @@ void gen_load(Context *c, YYLTYPE *locp, HexValue *width,
if (signedness == SIGNED) {
OUT(c, locp, " | MO_SIGN");
}
- OUT(c, locp, " | MO_LE);\n");
+ OUT(c, locp, " | MO_LE | MO_ALIGN);\n");
}
void gen_store(Context *c, YYLTYPE *locp, HexValue *width, HexValue *ea,
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index 8a32d5f79c..a5b9c24c6b 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -106,37 +106,37 @@
#define MEM_LOAD1s(DST, VA) \
do { \
CHECK_NOSHUF(VA, 1); \
- tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_SB); \
+ tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_SB | MO_ALIGN); \
} while (0)
#define MEM_LOAD1u(DST, VA) \
do { \
CHECK_NOSHUF(VA, 1); \
- tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_UB); \
+ tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_UB | MO_ALIGN); \
} while (0)
#define MEM_LOAD2s(DST, VA) \
do { \
CHECK_NOSHUF(VA, 2); \
- tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_LE | MO_SW); \
+ tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_LE | MO_SW | MO_ALIGN); \
} while (0)
#define MEM_LOAD2u(DST, VA) \
do { \
CHECK_NOSHUF(VA, 2); \
- tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_LE | MO_UW); \
+ tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_LE | MO_UW | MO_ALIGN); \
} while (0)
#define MEM_LOAD4s(DST, VA) \
do { \
CHECK_NOSHUF(VA, 4); \
- tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_LE | MO_SL); \
+ tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_LE | MO_SL | MO_ALIGN); \
} while (0)
#define MEM_LOAD4u(DST, VA) \
do { \
CHECK_NOSHUF(VA, 4); \
- tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_LE | MO_UL); \
+ tcg_gen_qemu_ld_tl(DST, VA, ctx->mem_idx, MO_LE | MO_UL | MO_ALIGN); \
} while (0)
#define MEM_LOAD8u(DST, VA) \
do { \
CHECK_NOSHUF(VA, 8); \
- tcg_gen_qemu_ld_i64(DST, VA, ctx->mem_idx, MO_LE | MO_UQ); \
+ tcg_gen_qemu_ld_i64(DST, VA, ctx->mem_idx, MO_LE | MO_UQ | MO_ALIGN); \
} while (0)
#define MEM_STORE1_FUNC(X) \
@@ -519,9 +519,15 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int shift)
#define fLOAD(NUM, SIZE, SIGN, EA, DST) MEM_LOAD##SIZE##SIGN(DST, EA)
#else
#define MEM_LOAD1 cpu_ldub_data_ra
-#define MEM_LOAD2 cpu_lduw_le_data_ra
-#define MEM_LOAD4 cpu_ldl_le_data_ra
-#define MEM_LOAD8 cpu_ldq_le_data_ra
+#define MEM_LOAD2(ENV, EA, RA) \
+ cpu_ldw_mmu(ENV, EA, make_memop_idx(MO_LEUW | MO_ALIGN, \
+ cpu_mmu_index(env_cpu(ENV), false)), RA)
+#define MEM_LOAD4(ENV, EA, RA) \
+ cpu_ldl_mmu(ENV, EA, make_memop_idx(MO_LEUL | MO_ALIGN, \
+ cpu_mmu_index(env_cpu(ENV), false)), RA)
+#define MEM_LOAD8(ENV, EA, RA) \
+ cpu_ldq_mmu(ENV, EA, make_memop_idx(MO_LEUQ | MO_ALIGN, \
+ cpu_mmu_index(env_cpu(ENV), false)), RA)
#define fLOAD(NUM, SIZE, SIGN, EA, DST) \
do { \