public inbox for qemu-devel@nongnu.org
 help / color / mirror / Atom feed
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
>
>


  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