From: Brian Cain <brian.cain@oss.qualcomm.com>
To: qemu-devel@nongnu.org, stefanha@redhat.com
Cc: brian.cain@oss.qualcomm.com,
Taylor Simpson <ltaylorsimpson@gmail.com>,
Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>,
Marco Liebel <marco.liebel@oss.qualcomm.com>,
Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Subject: [PULL 7/9] tests/tcg/hexagon: Add test for revision-gated instruction decoding
Date: Thu, 23 Apr 2026 19:36:04 -0700 [thread overview]
Message-ID: <20260424023606.2556830-8-brian.cain@oss.qualcomm.com> (raw)
In-Reply-To: <20260424023606.2556830-1-brian.cain@oss.qualcomm.com>
Add check_rev_gating, a linux-user test that verifies the decoder
rejects instructions from a newer CPU revision than the one selected
by the ELF binary's e_flags.
Co-authored-by: Taylor Simpson <ltaylorsimpson@gmail.com>
Co-authored-by: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>
Reviewed-by: Marco Liebel <marco.liebel@oss.qualcomm.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
tests/tcg/hexagon/check_rev_gating.c | 141 +++++++++++++++++++++++++++
tests/tcg/hexagon/Makefile.target | 6 ++
2 files changed, 147 insertions(+)
create mode 100644 tests/tcg/hexagon/check_rev_gating.c
diff --git a/tests/tcg/hexagon/check_rev_gating.c b/tests/tcg/hexagon/check_rev_gating.c
new file mode 100644
index 00000000000..26b66f54552
--- /dev/null
+++ b/tests/tcg/hexagon/check_rev_gating.c
@@ -0,0 +1,141 @@
+/*
+ * Test that instructions from a newer revision than the running CPU
+ * are rejected with SIGILL.
+ *
+ * Compiled with -mv66 so that e_flags selects CPU v66. The test embeds
+ * a v68 instruction (L2_loadw_aq: "r0 = memw_aq(r0)") via .word
+ * encoding. The revision-gated decoder must reject it, and linux-user
+ * must deliver SIGILL.
+ *
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <assert.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static void *resume_pc;
+static int signals_handled;
+static int expected_signals;
+
+static void handle_sigill(int sig, siginfo_t *info, void *puc)
+{
+ ucontext_t *uc = (ucontext_t *)puc;
+
+ if (sig != SIGILL) {
+ _exit(EXIT_FAILURE);
+ }
+
+ uc->uc_mcontext.r0 = SIGILL;
+ uc->uc_mcontext.pc = (unsigned long)resume_pc;
+ signals_handled++;
+}
+
+/*
+ * Try to execute an instruction introduced after v66
+ * On a v66 CPU this must raise SIGILL.
+ *
+ * Since we are building for v66, the assembler will reject
+ * the instructions, so introduce them with .word.
+ */
+#define TRY_FUNC(NAME, WORD) \
+static int try_##NAME(void) \
+{ \
+ int sig; \
+ expected_signals++; \
+ asm volatile( \
+ "r0 = #0\n" \
+ "r1 = ##1f\n" \
+ "memw(%1) = r1\n" \
+ WORD \
+ "1:\n" \
+ "%0 = r0\n" \
+ : "=r"(sig) \
+ : "r"(&resume_pc) \
+ : "r0", "r1", "memory"); \
+ return sig; \
+}
+
+TRY_FUNC(v68_loadw_aq,
+ ".word 0x9200c800 /* { r0 = memw_aq(r0) } */\n")
+TRY_FUNC(v68_loadd_aq,
+ ".word 0x9201d800 /* r1:0 = memd_aq(r1) */\n")
+TRY_FUNC(v68_release_at,
+ ".word 0xa0e0c00c /* release(r0):at */\n")
+TRY_FUNC(v68_release_st,
+ ".word 0xa0e0c02c /* release(r0):st */\n")
+TRY_FUNC(v68_storew_rl_at,
+ ".word 0xa0a0c108 /* memw_rl(r0):at = r1 */\n")
+TRY_FUNC(v68_stored_rl_at,
+ ".word 0xa0e2c008 /* memd_rl(r2):at = r1:0 */\n")
+TRY_FUNC(v68_storew_rl_st,
+ ".word 0xa0a0c128 /* memw_rl(r0):st = r1 */\n")
+TRY_FUNC(v68_stored_rl_st,
+ ".word 0xa0e2c028 /* memd_rl(r2):st = r1:0 */\n")
+
+TRY_FUNC(v68hvx_v6mpy,
+ ".word 0x1f42e424 /* v5:4.w = v6mpy(v5:4.ub, v3:2.b, #1):v */\n")
+
+TRY_FUNC(v69hvx_vasrvuhubrndsat,
+ ".word 0x1d06c465 /* v5.ub = vasr(v5:4.uh, v6.ub):rnd:sat */\n")
+TRY_FUNC(v69hvx_vasrvuhubsat,
+ ".word 0x1d06c445 /* v5.ub = vasr(v5:4.uh, v6.ub):sat */\n")
+TRY_FUNC(v69hvx_vasrvwuhrndsat,
+ ".word 0x1d06c425 /* v5.uh = vasr(v5:4.w, v6.uh):rnd:sat */\n")
+TRY_FUNC(v69hvx_vasrvwuhsat,
+ ".word 0x1d06c405 /* v5.uh = vasr(v5:4.w, v6.uh):sat */\n")
+TRY_FUNC(v69hvx_vassign_tmp,
+ ".word 0x1e014dcc /* { v12.tmp = v13 */\n"
+ ".word 0x1c43cc04 /* v4.w = vadd(v12.w, v3.w) } */\n")
+TRY_FUNC(v69hvx_vcombine_tmp,
+ ".word 0x1eae4fec /* { v13:12.tmp = vcombine(v15, v14) */\n"
+ ".word 0x1c434c04 /* v4.w = vadd(v12.w, v3.w) */\n"
+ ".word 0x1e03edf0 /* v16 = v13 } */\n")
+TRY_FUNC(v69hvx_vmpyuhvs,
+ ".word 0x1fc5e4e4 /* v4.uh = vmpy(V4.uh, v5.uh):>>16 */\n")
+
+TRY_FUNC(v73_callrh,
+ ".word 0x50c5c000 /* callrh r5 */\n")
+TRY_FUNC(v73_jumprh,
+ ".word 0x52c0c000 /* jumprh r0 */\n")
+
+int main(void)
+{
+ struct sigaction act;
+
+ memset(&act, 0, sizeof(act));
+ act.sa_sigaction = handle_sigill;
+ act.sa_flags = SA_SIGINFO;
+ assert(sigaction(SIGILL, &act, NULL) == 0);
+
+ assert(try_v68_loadw_aq() == SIGILL);
+ assert(try_v68_loadd_aq() == SIGILL);
+ assert(try_v68_release_at() == SIGILL);
+ assert(try_v68_release_st() == SIGILL);
+ assert(try_v68_storew_rl_at() == SIGILL);
+ assert(try_v68_stored_rl_at() == SIGILL);
+ assert(try_v68_storew_rl_st() == SIGILL);
+ assert(try_v68_stored_rl_st() == SIGILL);
+
+ assert(try_v68hvx_v6mpy() == SIGILL);
+
+ assert(try_v69hvx_vasrvuhubrndsat() == SIGILL);
+ assert(try_v69hvx_vasrvuhubsat() == SIGILL);
+ assert(try_v69hvx_vasrvwuhrndsat() == SIGILL);
+ assert(try_v69hvx_vasrvwuhsat() == SIGILL);
+ assert(try_v69hvx_vassign_tmp() == SIGILL);
+ assert(try_v69hvx_vcombine_tmp() == SIGILL);
+ assert(try_v69hvx_vmpyuhvs() == SIGILL);
+
+ assert(try_v73_callrh() == SIGILL);
+ assert(try_v73_jumprh() == SIGILL);
+
+ assert(signals_handled == expected_signals);
+
+ puts("PASS");
+ return EXIT_SUCCESS;
+}
diff --git a/tests/tcg/hexagon/Makefile.target b/tests/tcg/hexagon/Makefile.target
index 549c95082f6..09f0502abc5 100644
--- a/tests/tcg/hexagon/Makefile.target
+++ b/tests/tcg/hexagon/Makefile.target
@@ -81,6 +81,7 @@ HEX_TESTS += test_vminh
HEX_TESTS += test_vpmpyh
HEX_TESTS += test_vspliceb
+HEX_TESTS += check_rev_gating
HEX_TESTS += test_pnew_jump_loads
HEX_TESTS += v68_scalar
@@ -109,6 +110,11 @@ reg_mut: reg_mut.c hex_test.h
test_pnew_jump_loads: test_pnew_jump_loads.c hex_test.h
unaligned_pc: unaligned_pc.c
+# Compile for v66 so that the ELF selects a v66 CPU; the test then
+# exercises revision gating by executing a v68 .word instruction.
+check_rev_gating: check_rev_gating.c
+ $(CC) $(CFLAGS) -mv66 -O2 $< -o $@ $(LDFLAGS)
+
# This test has to be compiled for the -mv67t target
usr: usr.c hex_test.h
$(CC) $(CFLAGS) -mv67t -O2 -Wno-inline-asm -Wno-expansion-to-defined $< -o $@ $(LDFLAGS)
--
2.34.1
next prev parent reply other threads:[~2026-04-24 2:38 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-24 2:35 [PULL 0/9] hex queue Brian Cain
2026-04-24 2:35 ` [PULL 1/9] Hexagon (target/hexagon) Properly handle Hexagon CPU version Brian Cain
2026-04-24 2:35 ` [PULL 2/9] Hexagon (linux-user/hexagon) Identify Hexagon version in ELF file Brian Cain
2026-04-24 2:36 ` [PULL 3/9] Hexagon (target/hexagon) Add Hexagon definition field to DisasContext Brian Cain
2026-04-24 2:36 ` [PULL 4/9] Hexagon (target/hexagon) Introduce tag_rev_info.c.inc Brian Cain
2026-04-24 2:36 ` [PULL 5/9] Hexagon (target/hexagon) Check each opcode against current CPU definition Brian Cain
2026-04-24 2:36 ` [PULL 6/9] Hexagon (target/hexagon) Disassembly of invalid packets Brian Cain
2026-04-24 2:36 ` Brian Cain [this message]
2026-04-24 2:36 ` [PULL 8/9] Hexagon (target/hexagon) Remove snprint_a_pkt_debug Brian Cain
2026-04-24 2:36 ` [PULL 9/9] target/hexagon: Change DisasContext packet type Brian Cain
2026-04-25 16:59 ` [PULL 0/9] hex queue Stefan Hajnoczi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260424023606.2556830-8-brian.cain@oss.qualcomm.com \
--to=brian.cain@oss.qualcomm.com \
--cc=ltaylorsimpson@gmail.com \
--cc=marco.liebel@oss.qualcomm.com \
--cc=matheus.bernardino@oss.qualcomm.com \
--cc=pierrick.bouvier@oss.qualcomm.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.