All of lore.kernel.org
 help / color / mirror / Atom feed
* [PULL 00/12] Hexagon fix queue
@ 2026-07-17 19:15 Brian Cain
  2026-07-17 19:15 ` [PULL 01/12] tests/docker: hexagon fix podman untar, 22.1.8 Brian Cain
                   ` (12 more replies)
  0 siblings, 13 replies; 14+ messages in thread
From: Brian Cain @ 2026-07-17 19:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: brian.cain, stefanha

The following changes since commit 5ef0ecc5942ee07bb581cc96a97bbfc0fdf4005c:

  Merge tag 'hw-misc-20260714' of https://github.com/philmd/qemu into staging (2026-07-17 10:01:52 +0100)

are available in the Git repository at:

  https://github.com/qualcomm/qemu tags/hex-next-express-pull-request

for you to fetch changes up to 260d15c45b938511ade1992d7ff3efe47b7519bf:

  tests/functional/hexagon: add arch_tests functional test (2026-07-17 10:04:45 -0700)

----------------------------------------------------------------
Hexagon fix queue

Fixes for these issues:

* fix unaligned scalar accesses (now correctly faults/raises exception)
* fix build error with --disable-hexagon-idef-parser and gcc 14
* fix system emulation bugs: packet sreg writes, PC stuck on non-COF TB-end
* fix debug accesses w/MMU

----------------------------------------------------------------

Brian Cain (11):
  tests/docker: hexagon fix podman untar, 22.1.8
  gitlab-ci: build hexagon-softmmu to enable functional test
  target/hexagon: fix -Wshadow=local build error on GCC 14
  target/hexagon: handle misaligned load/store cause codes in cpu_loop
  target/hexagon: raise SIGBUS on unaligned scalar loads
  target/hexagon: raise SIGBUS on unaligned scalar stores
  target/hexagon: raise SIGBUS on unaligned data access in sysemu
  tests/tcg/hexagon: add unaligned scalar test
  target/hexagon: initialize deferred sreg-write temps to current value
  target/hexagon: fix PC not advancing for non-COF TB-ending packets
  tests/functional/hexagon: add arch_tests functional test

Matheus Tavares Bernardino (1):
  target/hexagon: fix get_phys_addr_debug with in-page offset

 MAINTAINERS                                   |   1 +
 target/hexagon/gen_tcg.h                      |   4 +-
 target/hexagon/macros.h                       |  30 +++--
 target/hexagon/translate.h                    |   3 +
 linux-user/hexagon/cpu_loop.c                 |   5 +
 target/hexagon/cpu.c                          |  27 ++++
 target/hexagon/genptr.c                       |  24 ++--
 target/hexagon/idef-parser/parser-helpers.c   |   2 +-
 target/hexagon/op_helper.c                    |  13 +-
 target/hexagon/translate.c                    |  62 +++++----
 tests/tcg/hexagon/unaligned_data.c            | 118 ++++++++++++++++++
 .../dockerfiles/debian-hexagon-cross.docker   |  27 ++--
 .gitlab-ci.d/buildtest.yml                    |   4 +-
 tests/functional/hexagon/meson.build          |   5 +
 tests/functional/hexagon/test_arch_tests.py   |  57 +++++++++
 tests/functional/meson.build                  |   1 +
 tests/tcg/hexagon/Makefile.target             |   2 +
 17 files changed, 326 insertions(+), 59 deletions(-)
 create mode 100644 tests/tcg/hexagon/unaligned_data.c
 create mode 100644 tests/functional/hexagon/meson.build
 create mode 100755 tests/functional/hexagon/test_arch_tests.py

-- 
2.34.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PULL 01/12] tests/docker: hexagon fix podman untar, 22.1.8
  2026-07-17 19:15 [PULL 00/12] Hexagon fix queue Brian Cain
@ 2026-07-17 19:15 ` Brian Cain
  2026-07-17 19:15 ` [PULL 02/12] gitlab-ci: build hexagon-softmmu to enable functional test Brian Cain
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Brian Cain @ 2026-07-17 19:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: brian.cain, stefanha, Matheus Tavares Bernardino,
	Pierrick Bouvier, Alex Bennée

The debian-hexagon-cross image previously unpacked the codelinaro
clang+llvm hexagon toolchain by piping a .tar.zst archive straight
into "tar --zstd -xC". GNU tar restores the archive's stored file
modes on extraction, including lchmod() on symlinks. Under rootless
podman, where the build runs in a user namespace on overlay storage,
those chmod()/lchmod() calls are rejected with EPERM:

  tar: .../libclang_rt.builtins.a: Cannot change mode to rwxrwxrwx: \
       Operation not permitted
  tar: .../x86_64-linux-gnu: Cannot change mode to rwxr-xr-x: \
       Operation not permitted
  tar: Exiting with failure status due to previous errors

tar then exits non-zero and aborts the build, so debian-hexagon-cross
only builds reliably under docker, not rootless podman.

So instead we can switch to a different packaging.  clang, lld
come from LLVM Debian builds from apt.llvm.org, instead of custom ones for
hexagon.  And only the hexagon linux sysroot is required, avoiding the
tar issues.

Reviewed-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 .../dockerfiles/debian-hexagon-cross.docker   | 27 ++++++++++++-------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/tests/docker/dockerfiles/debian-hexagon-cross.docker b/tests/docker/dockerfiles/debian-hexagon-cross.docker
index 23e8bb2fb26..e07a2be37e2 100644
--- a/tests/docker/dockerfiles/debian-hexagon-cross.docker
+++ b/tests/docker/dockerfiles/debian-hexagon-cross.docker
@@ -17,13 +17,13 @@ RUN apt-get update && \
 # Install common build utilities
     apt-get install -y --no-install-recommends \
         curl \
+        wget \
+        gnupg \
+        lsb-release \
         ccache \
         xz-utils \
         zstd \
         ca-certificates \
-        libc++1 \
-        libc++abi1 \
-        libunwind-19 \
         bison \
         flex \
         git \
@@ -43,15 +43,22 @@ RUN apt-get update && \
     ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc && \
     dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt
 
-ENV TOOLCHAIN_INSTALL=/opt
-ENV TOOLCHAIN_RELEASE=22.1.0
-ENV TOOLCHAIN_BASENAME=clang+llvm-${TOOLCHAIN_RELEASE}-cross-hexagon-unknown-linux-musl
-ENV TOOLCHAIN_URL=https://artifacts.codelinaro.org/artifactory/codelinaro-toolchain-for-hexagon/${TOOLCHAIN_RELEASE}_/${TOOLCHAIN_BASENAME}.tar.zst
+ENV LLVM_VERSION=22
+ENV TOOLCHAIN_RELEASE=22.1.8
+ENV TOOLCHAIN_URL=https://artifacts.codelinaro.org/artifactory/codelinaro-toolchain-for-hexagon/${TOOLCHAIN_RELEASE}________/hexagon-debs-${TOOLCHAIN_RELEASE}________.tar.gz
 ENV CCACHE_WRAPPERSDIR=/usr/libexec/ccache-wrappers
-
-RUN curl -#SL "$TOOLCHAIN_URL" | tar --zstd -xC "$TOOLCHAIN_INSTALL"
-ENV PATH=$PATH:${TOOLCHAIN_INSTALL}/${TOOLCHAIN_BASENAME}/x86_64-linux-gnu/bin
 ENV MAKE=/usr/bin/make
+
+RUN curl -#SL https://apt.llvm.org/llvm.sh -o /tmp/llvm.sh && \
+    chmod +x /tmp/llvm.sh && \
+    DEBIAN_FRONTEND=noninteractive eatmydata /tmp/llvm.sh ${LLVM_VERSION} && \
+    rm -f /tmp/llvm.sh && \
+    mkdir -p /tmp/hexagon-debs && \
+    curl -#SL "$TOOLCHAIN_URL" | tar -xzC /tmp/hexagon-debs && \
+    DEBIAN_FRONTEND=noninteractive eatmydata \
+    apt-get install -y /tmp/hexagon-debs/*.deb && \
+    rm -rf /tmp/hexagon-debs
+
 # As a final step configure the user (if env is defined)
 ARG USER
 ARG UID
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PULL 02/12] gitlab-ci: build hexagon-softmmu to enable functional test
  2026-07-17 19:15 [PULL 00/12] Hexagon fix queue Brian Cain
  2026-07-17 19:15 ` [PULL 01/12] tests/docker: hexagon fix podman untar, 22.1.8 Brian Cain
@ 2026-07-17 19:15 ` Brian Cain
  2026-07-17 19:15 ` [PULL 03/12] target/hexagon: fix -Wshadow=local build error on GCC 14 Brian Cain
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Brian Cain @ 2026-07-17 19:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: brian.cain, stefanha, Thomas Huth, Pierrick Bouvier,
	Alex Bennée

Add hexagon-softmmu to build-system-debian's target list so that the
existing functional-system-debian job picks up hexagon functional
test.

Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 .gitlab-ci.d/buildtest.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml
index e2553e7326f..831d9a26742 100644
--- a/.gitlab-ci.d/buildtest.yml
+++ b/.gitlab-ci.d/buildtest.yml
@@ -70,8 +70,8 @@ build-system-debian:
   variables:
     IMAGE: debian
     CONFIGURE_ARGS: --with-coroutine=sigaltstack --enable-rust
-    TARGETS: arm-softmmu i386-softmmu riscv64-softmmu sh4eb-softmmu
-      sparc-softmmu xtensa-softmmu
+    TARGETS: arm-softmmu hexagon-softmmu i386-softmmu riscv64-softmmu
+      sh4eb-softmmu sparc-softmmu xtensa-softmmu
     MAKE_CHECK_ARGS: check-build
 
 check-system-debian:
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PULL 03/12] target/hexagon: fix -Wshadow=local build error on GCC 14
  2026-07-17 19:15 [PULL 00/12] Hexagon fix queue Brian Cain
  2026-07-17 19:15 ` [PULL 01/12] tests/docker: hexagon fix podman untar, 22.1.8 Brian Cain
  2026-07-17 19:15 ` [PULL 02/12] gitlab-ci: build hexagon-softmmu to enable functional test Brian Cain
@ 2026-07-17 19:15 ` Brian Cain
  2026-07-17 19:15 ` [PULL 04/12] target/hexagon: handle misaligned load/store cause codes in cpu_loop Brian Cain
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Brian Cain @ 2026-07-17 19:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: brian.cain, stefanha, Pierrick Bouvier

With --disable-hexagon-idef-parser, tcg_funcs_generated.c.inc fails
to build under GCC 14 with:

  error: declaration of 'HALF' shadows a previous local
  [-Werror=shadow=local]

This became a hard error with GCC ced651b7757e `c23: tag compatibility
rules for enums`.

After that GCC change, DECL_FILE_SCOPE_P is false for all
enumerators, so shadowing now falls under -Wshadow=local.

Rename the local variable to tmp_half to avoid the collision.

Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 target/hexagon/gen_tcg.h | 4 ++--
 target/hexagon/macros.h  | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index a28af0c245b..40e03781d36 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -414,7 +414,7 @@
 
 #define fGEN_TCG_STORE(SHORTCODE) \
     do { \
-        TCGv HALF G_GNUC_UNUSED = tcg_temp_new(); \
+        TCGv tmp_half G_GNUC_UNUSED = tcg_temp_new(); \
         TCGv BYTE G_GNUC_UNUSED = tcg_temp_new(); \
         SHORTCODE; \
     } while (0)
@@ -422,7 +422,7 @@
 #define fGEN_TCG_STORE_pcr(SHIFT, STORE) \
     do { \
         TCGv ireg = tcg_temp_new(); \
-        TCGv HALF G_GNUC_UNUSED = tcg_temp_new(); \
+        TCGv tmp_half G_GNUC_UNUSED = tcg_temp_new(); \
         TCGv BYTE G_GNUC_UNUSED = tcg_temp_new(); \
         tcg_gen_mov_tl(EA, RxV); \
         gen_read_ireg(ireg, MuV, SHIFT); \
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index 21ab8ae5bbf..8a32d5f79c2 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -576,8 +576,8 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int shift)
     } while (0)
 
 #ifdef QEMU_GENERATE
-#define fGETHALF(N, SRC)  gen_get_half(HALF, N, SRC, true)
-#define fGETUHALF(N, SRC) gen_get_half(HALF, N, SRC, false)
+#define fGETHALF(N, SRC)  gen_get_half(tmp_half, N, SRC, true)
+#define fGETUHALF(N, SRC) gen_get_half(tmp_half, N, SRC, false)
 #else
 #define fGETHALF(N, SRC) ((int16_t)((SRC >> ((N) * 16)) & 0xffff))
 #define fGETUHALF(N, SRC) ((uint16_t)((SRC >> ((N) * 16)) & 0xffff))
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PULL 04/12] target/hexagon: handle misaligned load/store cause codes in cpu_loop
  2026-07-17 19:15 [PULL 00/12] Hexagon fix queue Brian Cain
                   ` (2 preceding siblings ...)
  2026-07-17 19:15 ` [PULL 03/12] target/hexagon: fix -Wshadow=local build error on GCC 14 Brian Cain
@ 2026-07-17 19:15 ` Brian Cain
  2026-07-17 19:15 ` [PULL 05/12] target/hexagon: raise SIGBUS on unaligned scalar loads Brian Cain
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Brian Cain @ 2026-07-17 19:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: brian.cain, stefanha, Pierrick Bouvier,
	Matheus Tavares Bernardino, Laurent Vivier, Helge Deller

Add a linux-user cpu_loop handler for HEX_CAUSE_MISALIGNED_LOAD and
HEX_CAUSE_MISALIGNED_STORE, raising SIGBUS for consistency with
hexswi.c's sysemu handling, even though linux-user's own alignment
check in accel/tcg/user-exec.c currently raises SIGBUS before
Hexagon's cause-code machinery is reached.

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>
---
 linux-user/hexagon/cpu_loop.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c
index 0958c51fbb3..d7f73439dbc 100644
--- a/linux-user/hexagon/cpu_loop.c
+++ b/linux-user/hexagon/cpu_loop.c
@@ -76,6 +76,11 @@ void cpu_loop(CPUHexagonState *env)
             force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC,
                     env->gpr[HEX_REG_PC]);
             break;
+            case HEX_CAUSE_MISALIGNED_LOAD:
+            case HEX_CAUSE_MISALIGNED_STORE:
+            force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN,
+                    env->gpr[HEX_REG_PC]);
+            break;
             default:
                 EXCP_DUMP(env, "\nqemu: unhandled CPU precise exception "
                     "cause code 0x%x - aborting\n",
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PULL 05/12] target/hexagon: raise SIGBUS on unaligned scalar loads
  2026-07-17 19:15 [PULL 00/12] Hexagon fix queue Brian Cain
                   ` (3 preceding siblings ...)
  2026-07-17 19:15 ` [PULL 04/12] target/hexagon: handle misaligned load/store cause codes in cpu_loop Brian Cain
@ 2026-07-17 19:15 ` Brian Cain
  2026-07-17 19:15 ` [PULL 06/12] target/hexagon: raise SIGBUS on unaligned scalar stores Brian Cain
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Brian Cain @ 2026-07-17 19:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: brian.cain, stefanha, Pierrick Bouvier,
	Matheus Tavares Bernardino, Alessandro Di Federico,
	Anton Johansson

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>
---
 target/hexagon/macros.h                     | 26 +++++++++++++--------
 target/hexagon/genptr.c                     |  6 ++---
 target/hexagon/idef-parser/parser-helpers.c |  2 +-
 3 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index 8a32d5f79c2..a5b9c24c6bb 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 { \
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 1ebc7471409..05c9aa04467 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 b942d9ea16b..49cc11fddd8 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,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PULL 06/12] target/hexagon: raise SIGBUS on unaligned scalar stores
  2026-07-17 19:15 [PULL 00/12] Hexagon fix queue Brian Cain
                   ` (4 preceding siblings ...)
  2026-07-17 19:15 ` [PULL 05/12] target/hexagon: raise SIGBUS on unaligned scalar loads Brian Cain
@ 2026-07-17 19:15 ` Brian Cain
  2026-07-17 19:15 ` [PULL 07/12] target/hexagon: raise SIGBUS on unaligned data access in sysemu Brian Cain
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Brian Cain @ 2026-07-17 19:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: brian.cain, stefanha, Pierrick Bouvier,
	Matheus Tavares Bernardino

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>
---
 target/hexagon/genptr.c    |  4 ++--
 target/hexagon/op_helper.c | 13 ++++++++++---
 target/hexagon/translate.c |  6 +++---
 3 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 05c9aa04467..f48a27bc09b 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 125952aee59..3ce223caba3 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 77235916f4b..5d54ce8caa4 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:
             {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PULL 07/12] target/hexagon: raise SIGBUS on unaligned data access in sysemu
  2026-07-17 19:15 [PULL 00/12] Hexagon fix queue Brian Cain
                   ` (5 preceding siblings ...)
  2026-07-17 19:15 ` [PULL 06/12] target/hexagon: raise SIGBUS on unaligned scalar stores Brian Cain
@ 2026-07-17 19:15 ` Brian Cain
  2026-07-17 19:15 ` [PULL 08/12] tests/tcg/hexagon: add unaligned scalar test Brian Cain
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Brian Cain @ 2026-07-17 19:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: brian.cain, stefanha, Pierrick Bouvier,
	Matheus Tavares Bernardino

hexagon-softmmu had no enforcement of alignment for scalar loads and
stores: the MO_ALIGN flag added by the previous two commits triggers
TLB_INVALID_MASK/alignment faults in cputlb.c, but Hexagon's
TCGCPUOps did not implement do_unaligned_access, so the fault was
never delivered to the guest.

Add hexagon_cpu_do_unaligned_access(), which raises
HEX_CAUSE_MISALIGNED_LOAD/_STORE via the existing HEX_EVENT_PRECISE
path, mirroring raise_tlbmiss_exception()/raise_perm_exception().

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>
---
 target/hexagon/cpu.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index 42d93e5da47..e2af736a99d 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -637,6 +637,18 @@ static void raise_perm_exception(CPUState *cs, uint32_t VA, int slot,
     cs->exception_index = excp;
 }
 
+static void raise_misaligned_exception(CPUState *cs, uint32_t VA, int slot,
+                                       MMUAccessType access_type)
+{
+    CPUHexagonState *env = cpu_env(cs);
+    int32_t excp = (access_type == MMU_DATA_STORE) ?
+                   HEX_CAUSE_MISALIGNED_STORE : HEX_CAUSE_MISALIGNED_LOAD;
+
+    set_badva_regs(env, VA, slot, access_type);
+    cs->exception_index = HEX_EVENT_PRECISE;
+    env->cause_code = excp;
+}
+
 static const char *access_type_names[] = { "MMU_DATA_LOAD ", "MMU_DATA_STORE",
                                            "MMU_INST_FETCH" };
 
@@ -715,6 +727,18 @@ static vaddr hexagon_pointer_wrap(CPUState *cs, int mmu_idx,
     return result;
 }
 
+static G_NORETURN
+void hexagon_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
+                                     MMUAccessType access_type, int mmu_idx,
+                                     uintptr_t retaddr)
+{
+    CPUHexagonState *env = cpu_env(cs);
+
+    raise_misaligned_exception(cs, addr, 0, access_type);
+    do_raise_exception(env, cs->exception_index, env->gpr[HEX_REG_PC],
+                       retaddr);
+}
+
 #endif
 
 static const TCGCPUOps hexagon_tcg_ops = {
@@ -732,6 +756,7 @@ static const TCGCPUOps hexagon_tcg_ops = {
     .pointer_wrap = hexagon_pointer_wrap,
     .cpu_exec_reset = cpu_reset,
     .tlb_fill = hexagon_tlb_fill,
+    .do_unaligned_access = hexagon_cpu_do_unaligned_access,
     .cpu_exec_halt = hexagon_cpu_has_work,
     .do_interrupt = hexagon_cpu_do_interrupt,
 #endif /* !CONFIG_USER_ONLY */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PULL 08/12] tests/tcg/hexagon: add unaligned scalar test
  2026-07-17 19:15 [PULL 00/12] Hexagon fix queue Brian Cain
                   ` (6 preceding siblings ...)
  2026-07-17 19:15 ` [PULL 07/12] target/hexagon: raise SIGBUS on unaligned data access in sysemu Brian Cain
@ 2026-07-17 19:15 ` Brian Cain
  2026-07-17 19:15 ` [PULL 09/12] target/hexagon: fix get_phys_addr_debug with in-page offset Brian Cain
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Brian Cain @ 2026-07-17 19:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: brian.cain, stefanha, Pierrick Bouvier

Add unaligned_data.c to exercise unaligned memh/memw/memd accesses and
verify SIGBUS is raised and caught.

Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 tests/tcg/hexagon/unaligned_data.c | 118 +++++++++++++++++++++++++++++
 tests/tcg/hexagon/Makefile.target  |   2 +
 2 files changed, 120 insertions(+)
 create mode 100644 tests/tcg/hexagon/unaligned_data.c

diff --git a/tests/tcg/hexagon/unaligned_data.c b/tests/tcg/hexagon/unaligned_data.c
new file mode 100644
index 00000000000..e0375faafbe
--- /dev/null
+++ b/tests/tcg/hexagon/unaligned_data.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+/*
+ * Test that unaligned scalar loads raise SIGBUS.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <setjmp.h>
+#include <signal.h>
+
+int err;
+
+#include "hex_test.h"
+
+static bool sigbus_caught;
+static sigjmp_buf jmp_env;
+static uint64_t buf[2] = { 0, 0 };
+
+static void sigbus_handler(int sig, siginfo_t *info, void *puc)
+{
+    check32(sig, SIGBUS);
+    sigbus_caught = true;
+    siglongjmp(jmp_env, 1);
+}
+
+static void test_unaligned_load(int size, int offset)
+{
+    char *p = (char *)buf + offset;
+    uint32_t dummy32;
+    uint64_t dummy64;
+
+    sigbus_caught = false;
+    if (sigsetjmp(jmp_env, 1) == 0) {
+        switch (size) {
+        case 2:
+            asm volatile("%[dst] = memh(%[src])\n\t"
+                          : [dst] "=r"(dummy32) : [src] "r"(p) : "memory");
+            break;
+        case 4:
+            asm volatile("%[dst] = memw(%[src])\n\t"
+                          : [dst] "=r"(dummy32) : [src] "r"(p) : "memory");
+            break;
+        case 8:
+            asm volatile("%[dst] = memd(%[src])\n\t"
+                          : [dst] "=r"(dummy64) : [src] "r"(p) : "memory");
+            break;
+        default:
+            abort();
+        }
+    }
+    check32(sigbus_caught, true);
+}
+
+static void test_unaligned_store(int size, int offset)
+{
+    char *p = (char *)buf + offset;
+    uint32_t val32 = 0x11223344;
+    uint64_t val64 = 0x1122334455667788ULL;
+
+    sigbus_caught = false;
+    if (sigsetjmp(jmp_env, 1) == 0) {
+        switch (size) {
+        case 2:
+            asm volatile("memh(%[addr]) = %[val]\n\t"
+                          : : [addr] "r"(p), [val] "r"(val32) : "memory");
+            break;
+        case 4:
+            asm volatile("memw(%[addr]) = %[val]\n\t"
+                          : : [addr] "r"(p), [val] "r"(val32) : "memory");
+            break;
+        case 8:
+            asm volatile("memd(%[addr]) = %[val]\n\t"
+                          : : [addr] "r"(p), [val] "r"(val64) : "memory");
+            break;
+        default:
+            abort();
+        }
+    }
+    check32(sigbus_caught, true);
+}
+
+int main()
+{
+    struct sigaction act;
+
+    act.sa_sigaction = sigbus_handler;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = SA_SIGINFO;
+    chk_error(sigaction(SIGBUS, &act, NULL));
+
+    test_unaligned_load(2, 1);
+    test_unaligned_load(4, 1);
+    test_unaligned_load(4, 2);
+    test_unaligned_load(4, 3);
+    test_unaligned_load(8, 1);
+    test_unaligned_load(8, 4);
+
+    test_unaligned_store(2, 1);
+    test_unaligned_store(4, 1);
+    test_unaligned_store(4, 2);
+    test_unaligned_store(4, 3);
+    test_unaligned_store(8, 1);
+    test_unaligned_store(8, 4);
+
+    act.sa_handler = SIG_DFL;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = 0;
+    chk_error(sigaction(SIGBUS, &act, NULL));
+
+    puts(err ? "FAIL" : "PASS");
+    return err ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/tests/tcg/hexagon/Makefile.target b/tests/tcg/hexagon/Makefile.target
index 70a8ec2e7fb..a2a0ffc69b2 100644
--- a/tests/tcg/hexagon/Makefile.target
+++ b/tests/tcg/hexagon/Makefile.target
@@ -54,6 +54,7 @@ HEX_TESTS += invalid-slots
 HEX_TESTS += invalid-encoding
 HEX_TESTS += multiple-writes
 HEX_TESTS += unaligned_pc
+HEX_TESTS += unaligned_data
 
 HEX_TESTS += test_abs
 HEX_TESTS += test_bitcnt
@@ -108,6 +109,7 @@ preg_alias: preg_alias.c hex_test.h
 read_write_overlap: read_write_overlap.c hex_test.h
 reg_mut: reg_mut.c hex_test.h
 test_pnew_jump_loads: test_pnew_jump_loads.c hex_test.h
+unaligned_data: unaligned_data.c hex_test.h
 unaligned_pc: unaligned_pc.c
 
 # Compile for v66 so that the ELF selects a v66 CPU; the test then
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PULL 09/12] target/hexagon: fix get_phys_addr_debug with in-page offset
  2026-07-17 19:15 [PULL 00/12] Hexagon fix queue Brian Cain
                   ` (7 preceding siblings ...)
  2026-07-17 19:15 ` [PULL 08/12] tests/tcg/hexagon: add unaligned scalar test Brian Cain
@ 2026-07-17 19:15 ` Brian Cain
  2026-07-17 19:15 ` [PULL 10/12] target/hexagon: initialize deferred sreg-write temps to current value Brian Cain
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Brian Cain @ 2026-07-17 19:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: brian.cain, stefanha, Matheus Tavares Bernardino,
	Pierrick Bouvier

From: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>

As documented:

     * @get_phys_addr_debug: Callback for obtaining a physical address.
     * This must be able to handle a non-page-aligned address, and will
     * return the physical address corresponding to that address.

When MMU is enabled, hexagon_cpu_get_phys_addr_debug() returns the
physical address page-aligned, not corrected to reflect the exact byte
the virtual addr maps to within the page. Let's fix that. The
MMU-disabled case is already correct.

This would break semihosting argument reads when it is added for Hexagon.

Signed-off-by: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 target/hexagon/cpu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index e2af736a99d..12d27ce1381 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -569,7 +569,9 @@ static hwaddr hexagon_cpu_get_phys_addr_debug(CPUState *cs, vaddr addr)
 
     if (get_physical_address(env, &phys_addr, &prot, &page_size, &excp,
                              addr, 0, mmu_idx)) {
+        vaddr page_offset = addr & (TARGET_PAGE_SIZE - 1);
         find_qemu_subpage(&addr, &phys_addr, page_size);
+        phys_addr += hexagon_cpu_mmu_enabled(env) ? page_offset : 0;
         return phys_addr;
     }
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PULL 10/12] target/hexagon: initialize deferred sreg-write temps to current value
  2026-07-17 19:15 [PULL 00/12] Hexagon fix queue Brian Cain
                   ` (8 preceding siblings ...)
  2026-07-17 19:15 ` [PULL 09/12] target/hexagon: fix get_phys_addr_debug with in-page offset Brian Cain
@ 2026-07-17 19:15 ` Brian Cain
  2026-07-17 19:15 ` [PULL 11/12] target/hexagon: fix PC not advancing for non-COF TB-ending packets Brian Cain
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Brian Cain @ 2026-07-17 19:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: brian.cain, stefanha, Pierrick Bouvier

Unconditionally allocate and initialize the temp to the sreg's current
value for every logged sreg write, rather than only allocating
when need_commit is set or the register is SSR.

Without this, reading a deferred sreg write within the same packet
before it is committed can observe an uninitialized temp instead
of the register's pre-packet value.

Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 target/hexagon/translate.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 5d54ce8caa4..115b6912553 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -615,9 +615,10 @@ static void gen_start_packet(DisasContext *ctx)
     }
     for (i = 0; i < ctx->sreg_log_idx; i++) {
         int reg_num = ctx->sreg_log[i];
-        if (reg_num < HEX_SREG_GLB_START &&
-            (ctx->need_commit || reg_num == HEX_SREG_SSR)) {
+        if (reg_num < HEX_SREG_GLB_START) {
             ctx->t_sreg_new_value[reg_num] = tcg_temp_new();
+            tcg_gen_mov_tl(ctx->t_sreg_new_value[reg_num],
+                          hex_t_sreg[reg_num]);
         }
     }
     for (i = 0; i < NUM_GREGS; i++) {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PULL 11/12] target/hexagon: fix PC not advancing for non-COF TB-ending packets
  2026-07-17 19:15 [PULL 00/12] Hexagon fix queue Brian Cain
                   ` (9 preceding siblings ...)
  2026-07-17 19:15 ` [PULL 10/12] target/hexagon: initialize deferred sreg-write temps to current value Brian Cain
@ 2026-07-17 19:15 ` Brian Cain
  2026-07-17 19:15 ` [PULL 12/12] tests/functional/hexagon: add arch_tests functional test Brian Cain
  2026-07-20 10:01 ` [PULL 00/12] Hexagon fix queue Stefan Hajnoczi
  12 siblings, 0 replies; 14+ messages in thread
From: Brian Cain @ 2026-07-17 19:15 UTC (permalink / raw)
  To: qemu-devel; +Cc: brian.cain, stefanha, Pierrick Bouvier

Add hex_next_PC, a global mirroring CPUHexagonState::next_PC,
and ctx->need_next_pc, so that gen_write_new_pc_addr() can write the
branch target through hex_next_PC instead of hex_gpr[HEX_REG_PC]
when a later unconditional write of PC is expected. gen_end_tb()
then commits hex_next_PC into hex_gpr[HEX_REG_PC] at the end of the
packet.

Previously, non-COF instructions that still end a TB did not advance the
PC, since next_PC's value was never written back into the PC register.

Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 target/hexagon/translate.h |  3 +++
 target/hexagon/genptr.c    | 14 ++++++++---
 target/hexagon/translate.c | 51 ++++++++++++++++++++++++++------------
 3 files changed, 49 insertions(+), 19 deletions(-)

diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index 0a7f37d5842..2fca157553b 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -40,6 +40,7 @@ typedef struct DisasContext {
     int reg_log_idx;
     DECLARE_BITMAP(regs_written, TOTAL_PER_THREAD_REGS);
     DECLARE_BITMAP(predicated_regs, TOTAL_PER_THREAD_REGS);
+    bool pkt_ends_tb;
     bool implicit_usr_write;
 #ifndef CONFIG_USER_ONLY
     int greg_log[GREG_WRITES_MAX];
@@ -75,6 +76,7 @@ typedef struct DisasContext {
     DECLARE_BITMAP(insn_qregs_read, NUM_QREGS);
     bool pre_commit;
     bool need_commit;
+    bool need_next_pc;
     TCGCond branch_cond;
     target_ulong branch_dest;
     bool is_tight_loop;
@@ -310,6 +312,7 @@ extern TCGv hex_gpr[TOTAL_PER_THREAD_REGS];
 extern TCGv hex_pred[NUM_PREGS];
 extern TCGv hex_slot_cancelled;
 extern TCGv hex_new_value_usr;
+extern TCGv hex_next_PC;
 extern TCGv hex_store_addr[STORES_MAX];
 extern TCGv_i32 hex_store_width[STORES_MAX];
 extern TCGv hex_store_val32[STORES_MAX];
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index f48a27bc09b..3f310377097 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -613,14 +613,22 @@ static void gen_write_new_pc_addr(DisasContext *ctx, TCGv addr,
         tcg_gen_brcondi_tl(cond, pred, 1, pred_false);
     }
 
+    /*
+     * If gen_end_tb() will unconditionally overwrite PC with hex_next_PC
+     * (because this packet has a predicated COF that may not execute),
+     * write the branch target there instead of directly into the PC
+     * global, or the overwrite in gen_end_tb() would clobber it.
+     */
+    TCGv pc_wr = ctx->need_next_pc ? hex_next_PC : hex_gpr[HEX_REG_PC];
+
     if (ctx->pkt.pkt_has_multi_cof) {
         /* If there are multiple branches in a packet, ignore the second one */
-        tcg_gen_movcond_tl(TCG_COND_NE, hex_gpr[HEX_REG_PC],
+        tcg_gen_movcond_tl(TCG_COND_NE, pc_wr,
                            ctx->branch_taken, tcg_constant_tl(0),
-                           hex_gpr[HEX_REG_PC], addr);
+                           pc_wr, addr);
         tcg_gen_movi_tl(ctx->branch_taken, 1);
     } else {
-        tcg_gen_mov_tl(hex_gpr[HEX_REG_PC], addr);
+        tcg_gen_mov_tl(pc_wr, addr);
     }
 
     if (cond != TCG_COND_ALWAYS) {
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 115b6912553..199b4f8c2ec 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -54,6 +54,7 @@ static const AnalyzeInsn opcode_analyze[XX_LAST_OPCODE] = {
 TCGv hex_gpr[TOTAL_PER_THREAD_REGS];
 TCGv hex_pred[NUM_PREGS];
 TCGv hex_slot_cancelled;
+TCGv hex_next_PC;
 TCGv hex_new_value_usr;
 TCGv hex_store_addr[STORES_MAX];
 TCGv_i32 hex_store_width[STORES_MAX];
@@ -184,10 +185,16 @@ static void gen_goto_tb(DisasContext *ctx, unsigned tb_slot_idx,
     }
 }
 
+static bool need_next_PC(DisasContext *ctx);
+
 static void gen_end_tb(DisasContext *ctx)
 {
     gen_exec_counters(ctx);
 
+    if (ctx->need_next_pc) {
+        tcg_gen_mov_tl(hex_gpr[HEX_REG_PC], hex_next_PC);
+    }
+
     if (ctx->branch_cond != TCG_COND_NEVER) {
         if (ctx->branch_cond != TCG_COND_ALWAYS) {
             TCGLabel *skip = gen_new_label();
@@ -391,17 +398,25 @@ static bool pkt_ends_tb(Packet *pkt)
 
 static bool need_next_PC(DisasContext *ctx)
 {
-    /* Check for conditional control flow or HW loop end */
-    for (int i = 0; i < ctx->pkt.num_insns; i++) {
-        uint16_t opcode = ctx->pkt.insn[i].opcode;
-        if (GET_ATTRIB(opcode, A_CONDEXEC) && GET_ATTRIB(opcode, A_COF)) {
-            return true;
-        }
-        if (GET_ATTRIB(opcode, A_HWLOOP0_END) ||
-            GET_ATTRIB(opcode, A_HWLOOP1_END)) {
-            return true;
+    Packet *pkt = &ctx->pkt;
+    if (pkt->pkt_has_cof || ctx->pkt_ends_tb) {
+        for (int i = 0; i < pkt->num_insns; i++) {
+            uint16_t opcode = pkt->insn[i].opcode;
+            if ((GET_ATTRIB(opcode, A_CONDEXEC) && GET_ATTRIB(opcode, A_COF)) ||
+                GET_ATTRIB(opcode, A_HWLOOP0_END) ||
+                GET_ATTRIB(opcode, A_HWLOOP1_END)) {
+                return true;
+            }
         }
     }
+    /*
+     * We end the TB on some instructions that do not change the flow (for
+     * other reasons). In these cases, we must set pc too, as the insn won't
+     * do it themselves.
+     */
+    if (ctx->pkt_ends_tb && !check_for_attrib(pkt, A_COF)) {
+        return true;
+    }
     return false;
 }
 
@@ -637,12 +652,14 @@ static void gen_start_packet(DisasContext *ctx)
     ctx->branch_taken = NULL;
     if (ctx->pkt.pkt_has_cof) {
         ctx->branch_taken = tcg_temp_new();
-        if (ctx->pkt.pkt_has_multi_cof) {
-            tcg_gen_movi_tl(ctx->branch_taken, 0);
-        }
-        if (need_next_PC(ctx)) {
-            tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], next_PC);
-        }
+    }
+    if (ctx->pkt.pkt_has_multi_cof) {
+        tcg_gen_movi_tl(ctx->branch_taken, 0);
+    }
+    ctx->pkt_ends_tb = pkt_ends_tb(&ctx->pkt);
+    ctx->need_next_pc = need_next_PC(ctx);
+    if (ctx->need_next_pc) {
+        tcg_gen_movi_tl(hex_next_PC, next_PC);
     }
 
     /* Preload the predicated registers into get_result_gpr(ctx, i) */
@@ -1142,7 +1159,7 @@ static void gen_commit_packet(DisasContext *ctx)
         ctx->pkt.vhist_insn->generate(ctx);
     }
 
-    if (pkt_ends_tb(&ctx->pkt) || ctx->base.is_jmp == DISAS_NORETURN) {
+    if (ctx->pkt_ends_tb || ctx->base.is_jmp == DISAS_NORETURN) {
         gen_end_tb(ctx);
     }
 }
@@ -1327,6 +1344,8 @@ void hexagon_translate_init(void)
     }
     hex_new_value_usr = tcg_global_mem_new(tcg_env,
         offsetof(CPUHexagonState, new_value_usr), "new_value_usr");
+    hex_next_PC = tcg_global_mem_new(tcg_env,
+        offsetof(CPUHexagonState, next_PC), "next_PC");
 
     for (i = 0; i < NUM_PREGS; i++) {
         hex_pred[i] = tcg_global_mem_new(tcg_env,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PULL 12/12] tests/functional/hexagon: add arch_tests functional test
  2026-07-17 19:15 [PULL 00/12] Hexagon fix queue Brian Cain
                   ` (10 preceding siblings ...)
  2026-07-17 19:15 ` [PULL 11/12] target/hexagon: fix PC not advancing for non-COF TB-ending packets Brian Cain
@ 2026-07-17 19:15 ` Brian Cain
  2026-07-20 10:01 ` [PULL 00/12] Hexagon fix queue Stefan Hajnoczi
  12 siblings, 0 replies; 14+ messages in thread
From: Brian Cain @ 2026-07-17 19:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: brian.cain, stefanha, Pierrick Bouvier, Thomas Huth,
	Philippe Mathieu-Daudé, Daniel P. Berrangé

Add new test cases from hexagon-arch-tests to exercise exceptions,
guest mode.

Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 MAINTAINERS                                 |  1 +
 tests/functional/hexagon/meson.build        |  5 ++
 tests/functional/hexagon/test_arch_tests.py | 57 +++++++++++++++++++++
 tests/functional/meson.build                |  1 +
 4 files changed, 64 insertions(+)
 create mode 100644 tests/functional/hexagon/meson.build
 create mode 100755 tests/functional/hexagon/test_arch_tests.py

diff --git a/MAINTAINERS b/MAINTAINERS
index ec56e5c5577..74fc43f5f20 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1357,6 +1357,7 @@ F: hw/hexagon/
 F: include/hw/hexagon/
 F: configs/devices/hexagon-softmmu/default.mak
 F: docs/system/hexagon/
+F: tests/functional/hexagon/
 F: docs/devel/hexagon-sys.rst
 
 LoongArch Machines
diff --git a/tests/functional/hexagon/meson.build b/tests/functional/hexagon/meson.build
new file mode 100644
index 00000000000..2b5a1a8f264
--- /dev/null
+++ b/tests/functional/hexagon/meson.build
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_hexagon_system_thorough = [
+  'arch_tests',
+]
diff --git a/tests/functional/hexagon/test_arch_tests.py b/tests/functional/hexagon/test_arch_tests.py
new file mode 100755
index 00000000000..54a1412c597
--- /dev/null
+++ b/tests/functional/hexagon/test_arch_tests.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python3
+#
+# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import QemuSystemTest, Asset
+from qemu_test.cmd import wait_for_console_pattern
+
+
+class ArchTestsUart(QemuSystemTest):
+    """
+    Hexagon architecture verification tests
+
+    These are bare-metal tests from hexagon-arch-tests that exercise
+    system functionality.
+
+    Tests output results via UART.
+    """
+    timeout = 60
+
+    ASSET_TARBALL = Asset(
+        "https://github.com/qualcomm/qemu-hexagon-testing/releases/"
+        "download/v0.2.5/arch_tests_uart.tar.gz",
+        "edb4f37b877a3a72a0e10920477458a43b40045d34398fee8cb763fefd342f4f",
+    )
+
+    def run_uart_test(self, test_name: str,
+                      machine: str = "virt") -> None:
+        """
+        Run an arch test binary and verify PASS via UART console output.
+        """
+        self.set_machine(machine)
+        self.archive_extract(self.ASSET_TARBALL)
+        target_bin = self.scratch_file('arch_tests_uart_package',
+                                      'bin', test_name)
+        self.vm.set_console()
+        self.set_vm_arg("-display", "none")
+        self.set_vm_arg("-kernel", target_bin)
+        self.vm.launch()
+        wait_for_console_pattern(self, "PASS")
+
+    def test_exceptions(self) -> None:
+        """Tests exception delivery for trap instructions, privilege
+        violations, and verifies SSR cause codes and ELR values.
+        """
+        self.run_uart_test("test_exceptions")
+
+    def test_guest_mode(self) -> None:
+        """Tests guest mode entry/exit via CCR configuration, verifying
+        GSR fields, GELR, and guest event vector table dispatch.
+        """
+        self.run_uart_test("test_guest_mode")
+
+
+if __name__ == "__main__":
+    QemuSystemTest.main()
diff --git a/tests/functional/meson.build b/tests/functional/meson.build
index c158197c4b7..c7362dd00ef 100644
--- a/tests/functional/meson.build
+++ b/tests/functional/meson.build
@@ -14,6 +14,7 @@ subdir('aarch64')
 subdir('alpha')
 subdir('arm')
 subdir('avr')
+subdir('hexagon')
 subdir('hppa')
 subdir('i386')
 subdir('loongarch64')
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PULL 00/12] Hexagon fix queue
  2026-07-17 19:15 [PULL 00/12] Hexagon fix queue Brian Cain
                   ` (11 preceding siblings ...)
  2026-07-17 19:15 ` [PULL 12/12] tests/functional/hexagon: add arch_tests functional test Brian Cain
@ 2026-07-20 10:01 ` Stefan Hajnoczi
  12 siblings, 0 replies; 14+ messages in thread
From: Stefan Hajnoczi @ 2026-07-20 10:01 UTC (permalink / raw)
  To: Brian Cain; +Cc: qemu-devel, brian.cain, stefanha

[-- Attachment #1: Type: text/plain, Size: 116 bytes --]

Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/11.1 for any user-visible changes.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2026-07-20 10:01 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-17 19:15 [PULL 00/12] Hexagon fix queue Brian Cain
2026-07-17 19:15 ` [PULL 01/12] tests/docker: hexagon fix podman untar, 22.1.8 Brian Cain
2026-07-17 19:15 ` [PULL 02/12] gitlab-ci: build hexagon-softmmu to enable functional test Brian Cain
2026-07-17 19:15 ` [PULL 03/12] target/hexagon: fix -Wshadow=local build error on GCC 14 Brian Cain
2026-07-17 19:15 ` [PULL 04/12] target/hexagon: handle misaligned load/store cause codes in cpu_loop Brian Cain
2026-07-17 19:15 ` [PULL 05/12] target/hexagon: raise SIGBUS on unaligned scalar loads Brian Cain
2026-07-17 19:15 ` [PULL 06/12] target/hexagon: raise SIGBUS on unaligned scalar stores Brian Cain
2026-07-17 19:15 ` [PULL 07/12] target/hexagon: raise SIGBUS on unaligned data access in sysemu Brian Cain
2026-07-17 19:15 ` [PULL 08/12] tests/tcg/hexagon: add unaligned scalar test Brian Cain
2026-07-17 19:15 ` [PULL 09/12] target/hexagon: fix get_phys_addr_debug with in-page offset Brian Cain
2026-07-17 19:15 ` [PULL 10/12] target/hexagon: initialize deferred sreg-write temps to current value Brian Cain
2026-07-17 19:15 ` [PULL 11/12] target/hexagon: fix PC not advancing for non-COF TB-ending packets Brian Cain
2026-07-17 19:15 ` [PULL 12/12] tests/functional/hexagon: add arch_tests functional test Brian Cain
2026-07-20 10:01 ` [PULL 00/12] Hexagon fix queue Stefan Hajnoczi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.