From: Alistair Francis <alistair23@gmail.com>
To: Nicholas Piggin <npiggin@gmail.com>
Cc: qemu-riscv@nongnu.org, qemu-devel@nongnu.org,
Laurent Vivier <laurent@vivier.eu>,
Pierrick Bouvier <pierrick.bouvier@linaro.org>,
Palmer Dabbelt <palmer@dabbelt.com>,
Alistair Francis <alistair.francis@wdc.com>,
Weiwei Li <liwei1518@gmail.com>,
Daniel Henrique Barboza <dbarboza@ventanamicro.com>,
Liu Zhiwei <zhiwei_liu@linux.alibaba.com>,
Richard Henderson <richard.henderson@linaro.org>,
Joel Stanley <joel@jms.id.au>
Subject: Re: [PATCH v3 5/5] tests/tcg/riscv64: Add vector state to signal test
Date: Wed, 25 Mar 2026 13:49:01 +1000 [thread overview]
Message-ID: <CAKmqyKM6vmxKB2SZeqeyUhpn-TxYrRrpssvbhkzS+o8KyErEPQ@mail.gmail.com> (raw)
In-Reply-To: <20260321141345.599105-6-npiggin@gmail.com>
On Sun, Mar 22, 2026 at 12:16 AM Nicholas Piggin <npiggin@gmail.com> wrote:
>
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> tests/tcg/riscv64/Makefile.target | 4 +-
> tests/tcg/riscv64/test-signal-handling.c | 226 ++++++++++++++++++++++-
> 2 files changed, 222 insertions(+), 8 deletions(-)
>
> diff --git a/tests/tcg/riscv64/Makefile.target b/tests/tcg/riscv64/Makefile.target
> index f318891396..86b6889a3d 100644
> --- a/tests/tcg/riscv64/Makefile.target
> +++ b/tests/tcg/riscv64/Makefile.target
> @@ -21,5 +21,5 @@ run-test-fcvtmod: QEMU_OPTS += -cpu rv64,d=true,zfa=true
>
> # Test signal handling.
> TESTS += test-signal-handling
> -test-signal-handling: CFLAGS += -march=rv64gc
> -run-test-signal-handling: QEMU_OPTS += -cpu rv64
> +test-signal-handling: CFLAGS += -march=rv64gcv
> +run-test-signal-handling: QEMU_OPTS += -cpu rv64,v=on
> diff --git a/tests/tcg/riscv64/test-signal-handling.c b/tests/tcg/riscv64/test-signal-handling.c
> index c202503382..b71fa6ee87 100644
> --- a/tests/tcg/riscv64/test-signal-handling.c
> +++ b/tests/tcg/riscv64/test-signal-handling.c
> @@ -19,10 +19,27 @@
> #include <execinfo.h>
> #include <unistd.h>
> #include <assert.h>
> +#include <sys/auxv.h>
> +#include <elf.h>
> #include <sys/mman.h>
> #include <ucontext.h>
> #include <asm/sigcontext.h>
>
> +#ifdef __riscv_v_intrinsic
> +#include <riscv_vector.h>
> +#else
> +static inline unsigned long __riscv_vlenb(void)
> +{
> + unsigned long vlenb;
> + __asm__ __volatile__ ("csrr %0, vlenb" : "=r" (vlenb));
> + return vlenb;
> +}
> +#endif
> +
> +#ifndef COMPAT_HWCAP_ISA_V
> +#define COMPAT_HWCAP_ISA_V (1 << ('V' - 'A'))
> +#endif
> +
> /*
> * This horrible hack seems to be required when including
> * signal.h and asm/sigcontext.h, to prevent sigcontext
> @@ -41,6 +58,10 @@ static uint64_t *signal_gvalues;
> static double *initial_fvalues;
> static double *final_fvalues;
> static double *signal_fvalues;
> +static size_t vlenb;
> +static uint8_t *initial_vvalues;
> +static uint8_t *final_vvalues;
> +static uint8_t *signal_vvalues;
>
> extern unsigned long unimp_addr[];
>
> @@ -64,6 +85,8 @@ static void ILL_handler(int signo, siginfo_t *info, void *context)
> {
> ucontext_t *uc = context;
> struct sigcontext *sc = (struct sigcontext *)&uc->uc_mcontext;
> + struct __riscv_ctx_hdr *sc_ext = &sc->sc_extdesc.hdr;
> + bool found_v = false;
>
> got_signal = true;
>
> @@ -82,12 +105,48 @@ static void ILL_handler(int signo, siginfo_t *info, void *context)
> }
> /* Test sc->sc_fpregs.d.fcsr ? */
>
> + assert(sc->sc_extdesc.reserved == 0);
> + while (sc_ext->magic != END_MAGIC) {
> + assert(sc_ext->size != 0);
> +
> + if (sc_ext->magic == RISCV_V_MAGIC) {
> + struct __sc_riscv_v_state *sc_v_state =
> + (struct __sc_riscv_v_state *)(sc_ext + 1);
> + struct __riscv_v_ext_state *v_state = &sc_v_state->v_state;
> +
> + found_v = true;
> +
> + assert(getauxval(AT_HWCAP) & COMPAT_HWCAP_ISA_V);
> +
> + assert(v_state->vlenb == vlenb);
> + assert(v_state->vtype == 0xc0); /* vma, vta */
> + assert(v_state->vl == vlenb);
> + assert(v_state->vstart == 0);
> + assert(v_state->vcsr == 0);
> +
> + uint64_t *vregs = v_state->datap;
> + for (int i = 0; i < 32; i++) {
> + for (int j = 0; j < vlenb; j += 8) {
> + size_t idx = (i * vlenb + j) / 8;
> + ((uint64_t *)signal_vvalues)[idx] = vregs[idx];
> + }
> + }
> + }
> +
> + sc_ext = (void *)sc_ext + sc_ext->size;
> + }
> +
> + assert(sc_ext->size == 0);
> + if (getauxval(AT_HWCAP) & COMPAT_HWCAP_ISA_V) {
> + assert(found_v);
> + }
> +
> sc->sc_regs.pc += 4;
> }
>
> static void init_test(void)
> {
> - int i;
> + int i, j;
>
> callchain_root = find_callchain_root();
>
> @@ -107,6 +166,19 @@ static void init_test(void)
> memset(final_fvalues, 0, 8 * 32);
> signal_fvalues = malloc(8 * 32);
> memset(signal_fvalues, 0, 8 * 32);
> +
> + vlenb = __riscv_vlenb();
> + initial_vvalues = malloc(vlenb * 32);
> + memset(initial_vvalues, 0, vlenb * 32);
> + for (i = 0; i < 32 ; i++) {
> + for (j = 0; j < vlenb; j++) {
> + initial_vvalues[i * vlenb + j] = i * vlenb + j;
> + }
> + }
> + final_vvalues = malloc(vlenb * 32);
> + memset(final_vvalues, 0, vlenb * 32);
> + signal_vvalues = malloc(vlenb * 32);
> + memset(signal_vvalues, 0, vlenb * 32);
> }
>
> static void run_test(void)
> @@ -179,6 +251,72 @@ static void run_test(void)
> "fld f29, 0xe8(t0)\n\t"
> "fld f30, 0xf0(t0)\n\t"
> "fld f31, 0xf8(t0)\n\t"
> + /* Load initial values into vector registers */
> + "mv t0, %[initial_vvalues]\n\t"
> + "vsetvli x0,%[vlenb],e8,m1,ta,ma\n\t"
> + "vle8.v v0, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v1, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v2, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v3, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v4, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v5, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v6, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v7, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v8, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v9, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v10, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v11, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v12, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v13, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v14, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v15, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v16, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v17, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v18, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v19, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v20, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v21, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v22, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v23, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v24, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v25, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v26, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v27, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v28, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v29, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v30, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vle8.v v31, (t0)\n\t"
> /* Trigger the SIGILL */
> ".global unimp_addr\n\t"
> "unimp_addr:\n\t"
> @@ -251,19 +389,93 @@ static void run_test(void)
> "fsd f29, 0xe8(t0)\n\t"
> "fsd f30, 0xf0(t0)\n\t"
> "fsd f31, 0xf8(t0)\n\t"
> + /* Save final values from vector registers */
> + "mv t0, %[final_vvalues]\n\t"
> + "vse8.v v0, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v1, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v2, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v3, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v4, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v5, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v6, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v7, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v8, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v9, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v10, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v11, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v12, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v13, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v14, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v15, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v16, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v17, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v18, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v19, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v20, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v21, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v22, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v23, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v24, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v25, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v26, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v27, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v28, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v29, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v30, (t0)\n\t"
> + "add t0, t0, %[vlenb]\n\t"
> + "vse8.v v31, (t0)\n\t"
> : "=m" (initial_gvalues),
> "=m" (final_gvalues),
> - "=m" (final_fvalues)
> - : "m" (initial_fvalues),
> + "=m" (final_fvalues),
> + "=m" (final_vvalues)
> + : [vlenb] "r" (vlenb),
> + "m" (initial_fvalues),
> + "m" (initial_vvalues),
> [initial_gvalues] "r" (initial_gvalues),
> [initial_fvalues] "r" (initial_fvalues),
> + [initial_vvalues] "r" (initial_vvalues),
> [final_gvalues] "r" (final_gvalues),
> - [final_fvalues] "r" (final_fvalues)
> + [final_fvalues] "r" (final_fvalues),
> + [final_vvalues] "r" (final_vvalues)
> : "t0",
> "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
> "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
> "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
> - "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31");
> + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
> + "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
> + "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
> + "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
> + "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31");
>
> assert(got_signal);
>
> @@ -272,7 +484,7 @@ static void run_test(void)
> * and is not a simple equality.
> */
> assert(initial_gvalues[4] == (unsigned long)initial_gvalues);
> - assert(signal_gvalues[4] == (unsigned long)initial_fvalues);
> + assert(signal_gvalues[4] == (unsigned long)initial_vvalues + 31 * vlenb);
> assert(final_gvalues[4] == (unsigned long)final_gvalues);
> initial_gvalues[4] = final_gvalues[4] = signal_gvalues[4] = 0;
>
> @@ -284,6 +496,8 @@ static void run_test(void)
> assert(!memcmp(initial_gvalues, signal_gvalues, 8 * 31));
> assert(!memcmp(initial_fvalues, final_fvalues, 8 * 32));
> assert(!memcmp(initial_fvalues, signal_fvalues, 8 * 32));
> + assert(!memcmp(initial_vvalues, signal_vvalues, vlenb * 32));
> + assert(!memcmp(initial_vvalues, final_vvalues, vlenb * 32));
> }
>
> int main(void)
> --
> 2.51.0
>
>
next prev parent reply other threads:[~2026-03-25 3:50 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-21 14:13 [PATCH v3 0/5] linux-user/riscv: add vector state to signal context Nicholas Piggin
2026-03-21 14:13 ` [PATCH v3 1/5] tests/tcg/riscv64: Add a user signal handling test Nicholas Piggin
2026-03-25 3:07 ` Alistair Francis
2026-03-21 14:13 ` [PATCH v3 2/5] linux-user/riscv: Allow restore_sigcontext to return error Nicholas Piggin
2026-03-25 3:07 ` Alistair Francis
2026-03-21 14:13 ` [PATCH v3 3/5] linux-user/riscv: Add extended state to sigcontext Nicholas Piggin
2026-03-25 3:14 ` Alistair Francis
2026-03-21 14:13 ` [PATCH v3 4/5] linux-user/riscv: Add vector state to signal context Nicholas Piggin
2026-03-25 3:45 ` Alistair Francis
2026-03-21 14:13 ` [PATCH v3 5/5] tests/tcg/riscv64: Add vector state to signal test Nicholas Piggin
2026-03-25 3:49 ` Alistair Francis [this message]
2026-03-25 4:45 ` [PATCH v3 0/5] linux-user/riscv: add vector state to signal context Alistair Francis
2026-03-26 6:22 ` Nicholas Piggin
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=CAKmqyKM6vmxKB2SZeqeyUhpn-TxYrRrpssvbhkzS+o8KyErEPQ@mail.gmail.com \
--to=alistair23@gmail.com \
--cc=alistair.francis@wdc.com \
--cc=dbarboza@ventanamicro.com \
--cc=joel@jms.id.au \
--cc=laurent@vivier.eu \
--cc=liwei1518@gmail.com \
--cc=npiggin@gmail.com \
--cc=palmer@dabbelt.com \
--cc=pierrick.bouvier@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-riscv@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=zhiwei_liu@linux.alibaba.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