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
