From: Brian Cain <bcain@quicinc.com>
To: "Matheus Bernardino (QUIC)" <quic_mathbern@quicinc.com>,
"qemu-devel@nongnu.org" <qemu-devel@nongnu.org>
Cc: Sid Manning <sidneym@quicinc.com>, "ale@rev.ng" <ale@rev.ng>,
"anjo@rev.ng" <anjo@rev.ng>,
"ltaylorsimpson@gmail.com" <ltaylorsimpson@gmail.com>,
"richard.henderson@linaro.org" <richard.henderson@linaro.org>,
Laurent Vivier <laurent@vivier.eu>
Subject: RE: [PATCH v6] Hexagon: add PC alignment check and exception
Date: Tue, 7 May 2024 23:40:15 +0000 [thread overview]
Message-ID: <CH3PR02MB10247B931B48C0CE3D3D031AAB8E42@CH3PR02MB10247.namprd02.prod.outlook.com> (raw)
In-Reply-To: <277b7aeda2c717a96d4dde936b3ac77707cb6517.1714755107.git.quic_mathbern@quicinc.com>
> -----Original Message-----
> From: Matheus Bernardino (QUIC) <quic_mathbern@quicinc.com>
> Sent: Friday, May 3, 2024 11:53 AM
> To: qemu-devel@nongnu.org
> Cc: Brian Cain <bcain@quicinc.com>; Sid Manning <sidneym@quicinc.com>;
> ale@rev.ng; anjo@rev.ng; ltaylorsimpson@gmail.com;
> richard.henderson@linaro.org; Laurent Vivier <laurent@vivier.eu>
> Subject: [PATCH v6] Hexagon: add PC alignment check and exception
>
> The Hexagon Programmer's Reference Manual says that the exception 0x1e
> should be raised upon an unaligned program counter. Let's implement that
> and also add some tests.
>
> Signed-off-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com>
> ---
> Changes in v6:
> - The multi COF test defines a new section for the unaligned label to
> make it more robust.
> - Instead of a nop in the undesired test branch, we use a trap for
> SYS_EXIT
>
Reviewed-by: Brian Cain <bcain@quicinc.com>
> target/hexagon/cpu.h | 7 ++
> target/hexagon/cpu_bits.h | 4 ++
> target/hexagon/macros.h | 3 -
> linux-user/hexagon/cpu_loop.c | 4 ++
> target/hexagon/op_helper.c | 9 ++-
> tests/tcg/hexagon/unaligned_pc.c | 107 ++++++++++++++++++++++++++++++
> tests/tcg/hexagon/Makefile.target | 2 +
> 7 files changed, 128 insertions(+), 8 deletions(-)
> create mode 100644 tests/tcg/hexagon/unaligned_pc.c
>
> diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
> index 3eef58fe8f..764f3c38cc 100644
> --- a/target/hexagon/cpu.h
> +++ b/target/hexagon/cpu.h
> @@ -134,6 +134,10 @@ struct ArchCPU {
>
> FIELD(TB_FLAGS, IS_TIGHT_LOOP, 0, 1)
>
> +G_NORETURN void hexagon_raise_exception_err(CPUHexagonState *env,
> + uint32_t exception,
> + uintptr_t pc);
> +
> static inline void cpu_get_tb_cpu_state(CPUHexagonState *env, vaddr *pc,
> uint64_t *cs_base, uint32_t *flags)
> {
> @@ -144,6 +148,9 @@ static inline void
> cpu_get_tb_cpu_state(CPUHexagonState *env, vaddr *pc,
> hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP, 1);
> }
> *flags = hex_flags;
> + if (*pc & PCALIGN_MASK) {
> + hexagon_raise_exception_err(env, HEX_EXCP_PC_NOT_ALIGNED, 0);
> + }
> }
>
> typedef HexagonCPU ArchCPU;
> diff --git a/target/hexagon/cpu_bits.h b/target/hexagon/cpu_bits.h
> index 96fef71729..4279281a71 100644
> --- a/target/hexagon/cpu_bits.h
> +++ b/target/hexagon/cpu_bits.h
> @@ -20,9 +20,13 @@
>
> #include "qemu/bitops.h"
>
> +#define PCALIGN 4
> +#define PCALIGN_MASK (PCALIGN - 1)
> +
> #define HEX_EXCP_FETCH_NO_UPAGE 0x012
> #define HEX_EXCP_INVALID_PACKET 0x015
> #define HEX_EXCP_INVALID_OPCODE 0x015
> +#define HEX_EXCP_PC_NOT_ALIGNED 0x01e
> #define HEX_EXCP_PRIV_NO_UREAD 0x024
> #define HEX_EXCP_PRIV_NO_UWRITE 0x025
>
> diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
> index 1376d6ccc1..f375471a98 100644
> --- a/target/hexagon/macros.h
> +++ b/target/hexagon/macros.h
> @@ -22,9 +22,6 @@
> #include "hex_regs.h"
> #include "reg_fields.h"
>
> -#define PCALIGN 4
> -#define PCALIGN_MASK (PCALIGN - 1)
> -
> #define GET_FIELD(FIELD, REGIN) \
> fEXTRACTU_BITS(REGIN, reg_field_info[FIELD].width, \
> reg_field_info[FIELD].offset)
> diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c
> index 7f1499ed28..d41159e52a 100644
> --- a/linux-user/hexagon/cpu_loop.c
> +++ b/linux-user/hexagon/cpu_loop.c
> @@ -60,6 +60,10 @@ void cpu_loop(CPUHexagonState *env)
> env->gpr[0] = ret;
> }
> break;
> + case HEX_EXCP_PC_NOT_ALIGNED:
> + force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN,
> + env->gpr[HEX_REG_R31]);
> + break;
> case EXCP_ATOMIC:
> cpu_exec_step_atomic(cs);
> break;
> diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
> index da10ac5847..ae5a605513 100644
> --- a/target/hexagon/op_helper.c
> +++ b/target/hexagon/op_helper.c
> @@ -36,10 +36,9 @@
> #define SF_MANTBITS 23
>
> /* Exceptions processing helpers */
> -static G_NORETURN
> -void do_raise_exception_err(CPUHexagonState *env,
> - uint32_t exception,
> - uintptr_t pc)
> +G_NORETURN void hexagon_raise_exception_err(CPUHexagonState *env,
> + uint32_t exception,
> + uintptr_t pc)
> {
> CPUState *cs = env_cpu(env);
> qemu_log_mask(CPU_LOG_INT, "%s: %d\n", __func__, exception);
> @@ -49,7 +48,7 @@ void do_raise_exception_err(CPUHexagonState *env,
>
> G_NORETURN void HELPER(raise_exception)(CPUHexagonState *env, uint32_t
> excp)
> {
> - do_raise_exception_err(env, excp, 0);
> + hexagon_raise_exception_err(env, excp, 0);
> }
>
> void log_store32(CPUHexagonState *env, target_ulong addr,
> diff --git a/tests/tcg/hexagon/unaligned_pc.c
> b/tests/tcg/hexagon/unaligned_pc.c
> new file mode 100644
> index 0000000000..e9dc7cb8b5
> --- /dev/null
> +++ b/tests/tcg/hexagon/unaligned_pc.c
> @@ -0,0 +1,107 @@
> +#include <stdio.h>
> +#include <signal.h>
> +#include <setjmp.h>
> +#include <stdlib.h>
> +
> +/* will be changed in signal handler */
> +volatile sig_atomic_t completed_tests;
> +static jmp_buf after_test;
> +static int nr_tests;
> +
> +void __attribute__((naked)) test_return(void)
> +{
> + asm volatile(
> + "allocframe(#0x8)\n"
> + "r0 = #0xffffffff\n"
> + "framekey = r0\n"
> + "dealloc_return\n"
> + :
> + :
> + : "r0", "r29", "r30", "r31", "framekey");
> +}
> +
> +void test_endloop(void)
> +{
> + asm volatile(
> + "loop0(1f, #2)\n"
> + "1: r0 = #0x3\n"
> + "sa0 = r0\n"
> + "{ nop }:endloop0\n"
> + :
> + :
> + : "r0", "sa0", "lc0", "usr");
> +}
> +
> +asm(
> + ".pushsection .text.unaligned\n"
> + ".org 0x3\n"
> + ".global test_multi_cof_unaligned\n"
> + "test_multi_cof_unaligned:\n"
> + " jumpr r31\n"
> + ".popsection\n"
> +);
> +
> +#define SYS_EXIT 94
> +
> +void test_multi_cof(void)
> +{
> + asm volatile(
> + "p0 = cmp.eq(r0, r0)\n"
> + "{\n"
> + " if (p0) jump test_multi_cof_unaligned\n"
> + " if (!p0) jump 1f\n"
> + "}\n"
> + "1:"
> + " r0 = #1\n"
> + " r6 = #%0\n"
> + " trap0(#1)\n"
> + :
> + : "i"(SYS_EXIT)
> + : "p0", "r0", "r6");
> +}
> +
> +void sigbus_handler(int signum)
> +{
> + /* retore framekey after test_return */
> + asm volatile(
> + "r0 = #0\n"
> + "framekey = r0\n"
> + :
> + :
> + : "r0", "framekey");
> + printf("Test %d complete\n", completed_tests);
> + completed_tests++;
> + siglongjmp(after_test, 1);
> +}
> +
> +void test_done(void)
> +{
> + int err = (completed_tests != nr_tests);
> + puts(err ? "FAIL" : "PASS");
> + exit(err);
> +}
> +
> +typedef void (*test_fn)(void);
> +
> +int main()
> +{
> + test_fn tests[] = { test_return, test_endloop, test_multi_cof, test_done };
> + nr_tests = (sizeof(tests) / sizeof(tests[0])) - 1;
> +
> + struct sigaction sa = {
> + .sa_sigaction = sigbus_handler,
> + .sa_flags = SA_SIGINFO
> + };
> +
> + if (sigaction(SIGBUS, &sa, NULL) < 0) {
> + perror("sigaction");
> + return EXIT_FAILURE;
> + }
> +
> + sigsetjmp(after_test, 1);
> + tests[completed_tests]();
> +
> + /* should never get here */
> + puts("FAIL");
> + return 1;
> +}
> diff --git a/tests/tcg/hexagon/Makefile.target
> b/tests/tcg/hexagon/Makefile.target
> index f839b2c0d5..e5182c01d8 100644
> --- a/tests/tcg/hexagon/Makefile.target
> +++ b/tests/tcg/hexagon/Makefile.target
> @@ -51,6 +51,7 @@ HEX_TESTS += scatter_gather
> HEX_TESTS += hvx_misc
> 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)
> @@ -107,6 +108,7 @@ overflow: overflow.c hex_test.h
> 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
> +unaligned_pc: unaligned_pc.c
>
> # This test has to be compiled for the -mv67t target
> usr: usr.c hex_test.h
> --
> 2.37.2
prev parent reply other threads:[~2024-05-07 23:41 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-03 16:53 [PATCH v6] Hexagon: add PC alignment check and exception Matheus Tavares Bernardino
2024-05-07 23:40 ` Brian Cain [this message]
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=CH3PR02MB10247B931B48C0CE3D3D031AAB8E42@CH3PR02MB10247.namprd02.prod.outlook.com \
--to=bcain@quicinc.com \
--cc=ale@rev.ng \
--cc=anjo@rev.ng \
--cc=laurent@vivier.eu \
--cc=ltaylorsimpson@gmail.com \
--cc=qemu-devel@nongnu.org \
--cc=quic_mathbern@quicinc.com \
--cc=richard.henderson@linaro.org \
--cc=sidneym@quicinc.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).