From: Brian Cain <[email protected]>

tests/tcg/hexagon: Handle SIGILL internally in invalid-slots test

Rewrite invalid-slots.c to catch and verify SIGILL using a sigaction
handler that modifies the ucontext, matching the pattern used by
invalid-encoding.c.

Co-authored-by: Matheus Tavares Bernardino <[email protected]>
Co-authored-by: Taylor Simpson <[email protected]>
Reviewed-by: Taylor Simpson <[email protected]>
Reviewed-by: Pierrick Bouvier <[email protected]>
Signed-off-by: Brian Cain <[email protected]>
Signed-off-by: Taylor Simpson <[email protected]>
---
 linux-user/hexagon/cpu_loop.c     |  4 ++
 target/hexagon/translate.c        | 19 +++++++-
 tests/tcg/hexagon/invalid-slots.c | 76 ++++++++++++++++++++++++-------
 tests/tcg/hexagon/Makefile.target |  6 ---
 4 files changed, 80 insertions(+), 25 deletions(-)

diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c
index 1941f4c9c1..c0e1098e3f 100644
--- a/linux-user/hexagon/cpu_loop.c
+++ b/linux-user/hexagon/cpu_loop.c
@@ -64,6 +64,10 @@ void cpu_loop(CPUHexagonState *env)
             force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN,
                             env->gpr[HEX_REG_R31]);
             break;
+        case HEX_CAUSE_INVALID_PACKET:
+            force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC,
+                            env->gpr[HEX_REG_PC]);
+            break;
         case EXCP_ATOMIC:
             cpu_exec_step_atomic(cs);
             break;
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 9498cd4502..78e0d6c219 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -198,6 +198,21 @@ static void gen_exception_end_tb(DisasContext *ctx, int 
excp)
 
 }
 
+/*
+ * Generate exception for decode failures. Unlike gen_exception_end_tb,
+ * this is used when decode fails before ctx->next_PC is initialized.
+ */
+static void gen_exception_decode_fail(DisasContext *ctx, int nwords, int excp)
+{
+    target_ulong fail_pc = ctx->base.pc_next + nwords * sizeof(uint32_t);
+
+    gen_exec_counters(ctx);
+    tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], fail_pc);
+    gen_exception_raw(excp);
+    ctx->base.is_jmp = DISAS_NORETURN;
+    ctx->base.pc_next = fail_pc;
+}
+
 static int read_packet_words(CPUHexagonState *env, DisasContext *ctx,
                              uint32_t words[])
 {
@@ -935,7 +950,7 @@ static void decode_and_translate_packet(CPUHexagonState 
*env, DisasContext *ctx)
 
     nwords = read_packet_words(env, ctx, words);
     if (!nwords) {
-        gen_exception_end_tb(ctx, HEX_CAUSE_INVALID_PACKET);
+        gen_exception_decode_fail(ctx, 0, HEX_CAUSE_INVALID_PACKET);
         return;
     }
 
@@ -950,7 +965,7 @@ static void decode_and_translate_packet(CPUHexagonState 
*env, DisasContext *ctx)
         gen_commit_packet(ctx);
         ctx->base.pc_next += pkt.encod_pkt_size_in_bytes;
     } else {
-        gen_exception_end_tb(ctx, HEX_CAUSE_INVALID_PACKET);
+        gen_exception_decode_fail(ctx, nwords, HEX_CAUSE_INVALID_PACKET);
     }
 }
 
diff --git a/tests/tcg/hexagon/invalid-slots.c 
b/tests/tcg/hexagon/invalid-slots.c
index 366ce4f42f..607027f314 100644
--- a/tests/tcg/hexagon/invalid-slots.c
+++ b/tests/tcg/hexagon/invalid-slots.c
@@ -1,29 +1,71 @@
 /*
- *  Copyright(c) 2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ * Test that invalid slot assignments are properly rejected.
  *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * 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 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;
+}
+
 char mem[8] __attribute__((aligned(8)));
 
-int main()
+/*
+ * Invalid packet with 2 instructions at slot 0:
+ * - Word 0: 0xa1804100 = memw(r0) = r1
+ * - Word 1: 0x28032804 = { r3 = #0; r4 = #0 }
+ *
+ * This should raise SIGILL due to the invalid slot assignment.
+ */
+static int test_invalid_slots(void)
 {
+    int sig;
+
     asm volatile(
+        "r0 = #0\n"
+        "r1 = ##1f\n"
+        "memw(%1) = r1\n"
         "r0 = #mem\n"
-        /* Invalid packet (2 instructions at slot 0): */
         ".word 0xa1804100\n" /* { memw(r0) = r1;      */
         ".word 0x28032804\n" /*   r3 = #0; r4 = #0 }  */
-        : : : "r0", "r3", "r4", "memory");
-    return 0;
+        "1:\n"
+        "%0 = r0\n"
+        : "=r"(sig)
+        : "r"(&resume_pc)
+        : "r0", "r1", "r3", "r4", "memory");
+
+    return sig;
+}
+
+int main()
+{
+    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(test_invalid_slots() == SIGILL);
+
+    puts("PASS");
+    return EXIT_SUCCESS;
 }
diff --git a/tests/tcg/hexagon/Makefile.target 
b/tests/tcg/hexagon/Makefile.target
index e5182c01d8..8c9d48fc4d 100644
--- a/tests/tcg/hexagon/Makefile.target
+++ b/tests/tcg/hexagon/Makefile.target
@@ -53,12 +53,6 @@ HEX_TESTS += hvx_histogram
 HEX_TESTS += invalid-slots
 HEX_TESTS += unaligned_pc
 
-run-and-check-exception = $(call run-test,$2,$3 2>$2.stderr; \
-       test $$? -eq 1 && grep -q "exception $(strip $1)" $2.stderr)
-
-run-invalid-slots: invalid-slots
-       $(call run-and-check-exception, 0x15, $@, $(QEMU) $(QEMU_OPTS) $<)
-
 HEX_TESTS += test_abs
 HEX_TESTS += test_bitcnt
 HEX_TESTS += test_bitsplit
-- 
2.43.0


Reply via email to