[v1, 2/2] selftests: Test RISC-V Vector's first-use handler

Andy Chiu andy.chiu at sifive.com
Tue Jun 27 08:39:15 PDT 2023


On Tue, Jun 27, 2023 at 3:46 PM Björn Töpel <bjorn at kernel.org> wrote:
>
> Andy Chiu <andy.chiu at sifive.com> writes:
>
> > This add a test to check if the kernel zero-initializes all V registers
> > after the first-use trap handler returns.
> >
> > If V registers are not zero-initialized, then the test should fail one
> > out of several runs:
> >
> > ```
> >  root at sifive-fpga:~# ./v_initval_nolibc
> >  # vl = 256
> >  not ok 1 detect stale values on v-regesters
> >  0 0 0 0 0 0 0 0   0 0 0 0 0 0 0 0
> >  0 4c 41 4e 47 3d 43 0   50 41 54 48 3d 2f 75 73
> >  72 2f 6c 6f 63 61 6c 2f   73 62 69 6e 3a 2f 75 73
> >  72 2f 6c 6f 63 61 6c 2f   62 69 6e 3a 2f 75 73 72
> >  ff ff 81 0 0 0 0 0   0 0 0 0 0 0 0 0
> > ```
> >
> > Otherwise, the test passes without errors each run.
> >
> > Signed-off-by: Andy Chiu <andy.chiu at sifive.com>
> > ---
> >  .../testing/selftests/riscv/vector/.gitignore |  1 +
> >  tools/testing/selftests/riscv/vector/Makefile |  6 +-
> >  .../selftests/riscv/vector/v_initval_nolibc.c | 68 +++++++++++++++++++
> >  3 files changed, 74 insertions(+), 1 deletion(-)
> >  create mode 100644 tools/testing/selftests/riscv/vector/v_initval_nolibc.c
> >
> > diff --git a/tools/testing/selftests/riscv/vector/.gitignore b/tools/testing/selftests/riscv/vector/.gitignore
> > index 4f2b4e8a3b08..9ae7964491d5 100644
> > --- a/tools/testing/selftests/riscv/vector/.gitignore
> > +++ b/tools/testing/selftests/riscv/vector/.gitignore
> > @@ -1,2 +1,3 @@
> >  vstate_exec_nolibc
> >  vstate_prctl
> > +v_initval_nolibc
> > diff --git a/tools/testing/selftests/riscv/vector/Makefile b/tools/testing/selftests/riscv/vector/Makefile
> > index cd6e80bf995d..bfff0ff4f3be 100644
> > --- a/tools/testing/selftests/riscv/vector/Makefile
> > +++ b/tools/testing/selftests/riscv/vector/Makefile
> > @@ -2,7 +2,7 @@
> >  # Copyright (C) 2021 ARM Limited
> >  # Originally tools/testing/arm64/abi/Makefile
> >
> > -TEST_GEN_PROGS := vstate_prctl
> > +TEST_GEN_PROGS := vstate_prctl v_initval_nolibc
> >  TEST_GEN_PROGS_EXTENDED := vstate_exec_nolibc
> >
> >  include ../../lib.mk
> > @@ -13,3 +13,7 @@ $(OUTPUT)/vstate_prctl: vstate_prctl.c ../hwprobe/sys_hwprobe.S
> >  $(OUTPUT)/vstate_exec_nolibc: vstate_exec_nolibc.c
> >       $(CC) -nostdlib -static -include ../../../../include/nolibc/nolibc.h \
> >               -Wall $(CFLAGS) $(LDFLAGS) $^ -o $@ -lgcc
> > +
> > +$(OUTPUT)/v_initval_nolibc: v_initval_nolibc.c
> > +     $(CC) -nostdlib -static -include ../../../../include/nolibc/nolibc.h \
> > +             -Wall $(CFLAGS) $(LDFLAGS) $^ -o $@ -lgcc
>
> Hmm, does this build with clang? (No, bigge on my end, and can be fixed
> later.)

Oops, I didn't try. I will respin the series if clang runs into
problems. I am not very confident here, but do we need to gate build
these tests if CONFIG_RISCV_ISA_V is not set? If my code fits clang
well then it probably would be some toolchain dependency issues
(guessing the ".option arch" part). Kconfig should be able to resolve
this part.

>
> > diff --git a/tools/testing/selftests/riscv/vector/v_initval_nolibc.c b/tools/testing/selftests/riscv/vector/v_initval_nolibc.c
> > new file mode 100644
> > index 000000000000..66764edb0d52
> > --- /dev/null
> > +++ b/tools/testing/selftests/riscv/vector/v_initval_nolibc.c
> > @@ -0,0 +1,68 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +
> > +#include "../../kselftest.h"
> > +#define MAX_VSIZE    (8192 * 32)
> > +
> > +void dump(char *ptr, int size)
> > +{
> > +     int i = 0;
> > +
> > +     for (i = 0; i < size; i++) {
> > +             if (i != 0) {
> > +                     if (i % 16 == 0)
> > +                             printf("\n");
> > +                     else if (i % 8 == 0)
> > +                             printf("  ");
> > +             }
> > +             printf("%02x ", ptr[i]);
> > +     }
> > +     printf("\n");
> > +}
> > +
> > +int main(void)
> > +{
> > +     int i;
> > +     unsigned long vl;
> > +     char *datap, *tmp;
> > +
> > +     datap = malloc(MAX_VSIZE);
> > +     if (!datap) {
> > +             ksft_test_result_fail("fail to allocate memory for size = %lu\n", MAX_VSIZE);
> > +             exit(-1);
> > +     }
> > +
> > +     tmp = datap;
> > +     asm volatile (
> > +             ".option push\n\t"
> > +             ".option arch, +v\n\t"
> > +             "vsetvli        %0, x0, e8, m8, ta, ma\n\t"
> > +             "vse8.v         v0, (%2)\n\t"
> > +             "add            %1, %2, %0\n\t"
> > +             "vse8.v         v8, (%1)\n\t"
> > +             "add            %1, %1, %0\n\t"
> > +             "vse8.v         v16, (%1)\n\t"
> > +             "add            %1, %1, %0\n\t"
> > +             "vse8.v         v24, (%1)\n\t"
> > +             ".option pop\n\t"
> > +             : "=&r" (vl), "=r" (tmp) : "r" (datap) : "memory");
> > +
> > +     ksft_print_msg("vl = %lu\n", vl);
> > +
> > +     if (datap[0] != 0x00 && datap[0] != 0xff) {
> > +             ksft_test_result_fail("v-regesters are not properly initialized\n");
>
> Nit: "v-registers"
>
> > +             dump(datap, vl * 4);
> > +             exit(-1);
> > +     }
> > +
> > +     for (i = 1; i < vl * 4; i++) {
> > +             if (datap[i] != datap[0]) {
> > +                     ksft_test_result_fail("detect stale values on v-regesters\n");
>
> Nit (dito): "v-registers", and maybe "detected".
>
>
> With, or without the changes above,
> Reviewed-by: Björn Töpel <bjorn at rivosinc.com>
>
> Björn

Thanks,
Andy



More information about the linux-riscv mailing list