* [PATCH] riscv: selftests: Add signal handling vector tests
@ 2024-04-03 23:50 Charlie Jenkins
2024-04-04 0:27 ` Vineet Gupta
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Charlie Jenkins @ 2024-04-03 23:50 UTC (permalink / raw)
To: Shuah Khan, Paul Walmsley, Palmer Dabbelt, Albert Ou, Andy Chiu,
Björn Töpel, Vineet Gupta
Cc: linux-kernel, linux-kselftest, linux-riscv, Charlie Jenkins
Add two tests to check vector save/restore when a signal is received
during a vector routine. One test ensures that a value is not clobbered
during signal handling. The other verifies that vector registers
modified in the signal handler are properly reflected when the signal
handling is complete.
Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
---
These tests came about to highlight the bug fixed in
https://lore.kernel.org/lkml/20240403072638.567446-1-bjorn@kernel.org/
and will only pass with that fix applied.
---
tools/testing/selftests/riscv/Makefile | 2 +-
tools/testing/selftests/riscv/sigreturn/.gitignore | 1 +
tools/testing/selftests/riscv/sigreturn/Makefile | 12 ++++
.../testing/selftests/riscv/sigreturn/sigreturn.c | 82 ++++++++++++++++++++++
4 files changed, 96 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/riscv/Makefile b/tools/testing/selftests/riscv/Makefile
index 4a9ff515a3a0..7ce03d832b64 100644
--- a/tools/testing/selftests/riscv/Makefile
+++ b/tools/testing/selftests/riscv/Makefile
@@ -5,7 +5,7 @@
ARCH ?= $(shell uname -m 2>/dev/null || echo not)
ifneq (,$(filter $(ARCH),riscv))
-RISCV_SUBTARGETS ?= hwprobe vector mm
+RISCV_SUBTARGETS ?= hwprobe vector mm sigreturn
else
RISCV_SUBTARGETS :=
endif
diff --git a/tools/testing/selftests/riscv/sigreturn/.gitignore b/tools/testing/selftests/riscv/sigreturn/.gitignore
new file mode 100644
index 000000000000..35002b8ae780
--- /dev/null
+++ b/tools/testing/selftests/riscv/sigreturn/.gitignore
@@ -0,0 +1 @@
+sigreturn
diff --git a/tools/testing/selftests/riscv/sigreturn/Makefile b/tools/testing/selftests/riscv/sigreturn/Makefile
new file mode 100644
index 000000000000..eb8bac9279a8
--- /dev/null
+++ b/tools/testing/selftests/riscv/sigreturn/Makefile
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (C) 2021 ARM Limited
+# Originally tools/testing/arm64/abi/Makefile
+
+CFLAGS += -I$(top_srcdir)/tools/include
+
+TEST_GEN_PROGS := sigreturn
+
+include ../../lib.mk
+
+$(OUTPUT)/sigreturn: sigreturn.c
+ $(CC) -static -o$@ $(CFLAGS) $(LDFLAGS) $^
diff --git a/tools/testing/selftests/riscv/sigreturn/sigreturn.c b/tools/testing/selftests/riscv/sigreturn/sigreturn.c
new file mode 100644
index 000000000000..62397d5934f1
--- /dev/null
+++ b/tools/testing/selftests/riscv/sigreturn/sigreturn.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+#include <linux/ptrace.h>
+#include "../../kselftest_harness.h"
+
+#define RISCV_V_MAGIC 0x53465457
+#define DEFAULT_VALUE 2
+#define SIGNAL_HANDLER_OVERRIDE 3
+
+static void simple_handle(int sig_no, siginfo_t *info, void *vcontext)
+{
+ ucontext_t *context = vcontext;
+
+ context->uc_mcontext.__gregs[REG_PC] = context->uc_mcontext.__gregs[REG_PC] + 4;
+}
+
+static void vector_override(int sig_no, siginfo_t *info, void *vcontext)
+{
+ ucontext_t *context = vcontext;
+
+ // vector state
+ struct __riscv_extra_ext_header *ext;
+ struct __riscv_v_ext_state *v_ext_state;
+
+ /* Find the vector context. */
+ ext = (void *)(&context->uc_mcontext.__fpregs);
+ if (ext->hdr.magic != RISCV_V_MAGIC) {
+ fprintf(stderr, "bad vector magic: %x\n", ext->hdr.magic);
+ abort();
+ }
+
+ v_ext_state = (void *)((char *)(ext) + sizeof(*ext));
+
+ *(int *)v_ext_state->datap = SIGNAL_HANDLER_OVERRIDE;
+
+ context->uc_mcontext.__gregs[REG_PC] = context->uc_mcontext.__gregs[REG_PC] + 4;
+}
+
+static int vector_sigreturn(int data, void (*handler)(int, siginfo_t *, void *))
+{
+ int after_sigreturn;
+ struct sigaction sig_action = {
+ .sa_sigaction = handler,
+ .sa_flags = SA_SIGINFO
+ };
+
+ sigaction(SIGSEGV, &sig_action, 0);
+
+ asm(".option push \n\
+ .option arch, +v \n\
+ vsetivli x0, 1, e32, ta, ma \n\
+ vmv.s.x v0, %1 \n\
+ # Generate SIGSEGV \n\
+ lw a0, 0(x0) \n\
+ vmv.x.s %0, v0 \n\
+ .option pop" : "=r" (after_sigreturn) : "r" (data));
+
+ return after_sigreturn;
+}
+
+TEST(vector_restore)
+{
+ int result;
+
+ result = vector_sigreturn(DEFAULT_VALUE, &simple_handle);
+
+ EXPECT_EQ(DEFAULT_VALUE, result);
+}
+
+TEST(vector_restore_signal_handler_override)
+{
+ int result;
+
+ result = vector_sigreturn(DEFAULT_VALUE, &vector_override);
+
+ EXPECT_EQ(SIGNAL_HANDLER_OVERRIDE, result);
+}
+
+TEST_HARNESS_MAIN
---
base-commit: 4cece764965020c22cff7665b18a012006359095
change-id: 20240403-vector_sigreturn_tests-8118f0ac54fa
--
- Charlie
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH] riscv: selftests: Add signal handling vector tests 2024-04-03 23:50 [PATCH] riscv: selftests: Add signal handling vector tests Charlie Jenkins @ 2024-04-04 0:27 ` Vineet Gupta 2024-04-04 0:43 ` Charlie Jenkins 2024-04-04 5:46 ` Björn Töpel ` (2 subsequent siblings) 3 siblings, 1 reply; 7+ messages in thread From: Vineet Gupta @ 2024-04-04 0:27 UTC (permalink / raw) To: Charlie Jenkins, Shuah Khan, Paul Walmsley, Palmer Dabbelt, Albert Ou, Andy Chiu, Björn Töpel Cc: linux-kernel, linux-kselftest, linux-riscv On 4/3/24 16:50, Charlie Jenkins wrote: > Add two tests to check vector save/restore when a signal is received > during a vector routine. One test ensures that a value is not clobbered > during signal handling. The other verifies that vector registers > modified in the signal handler are properly reflected when the signal > handling is complete. Hmm, isn't this testing two contradictory things ? We do want V regs to be not clobbered across a handled signal, o/w V enabled code would just not work at all. That implies that anything done by signal handler should just be discarded - no ? Am I missing something. -Vineet > > Signed-off-by: Charlie Jenkins <charlie@rivosinc.com> > --- > These tests came about to highlight the bug fixed in > https://lore.kernel.org/lkml/20240403072638.567446-1-bjorn@kernel.org/ > and will only pass with that fix applied. > --- > tools/testing/selftests/riscv/Makefile | 2 +- > tools/testing/selftests/riscv/sigreturn/.gitignore | 1 + > tools/testing/selftests/riscv/sigreturn/Makefile | 12 ++++ > .../testing/selftests/riscv/sigreturn/sigreturn.c | 82 ++++++++++++++++++++++ > 4 files changed, 96 insertions(+), 1 deletion(-) > > diff --git a/tools/testing/selftests/riscv/Makefile b/tools/testing/selftests/riscv/Makefile > index 4a9ff515a3a0..7ce03d832b64 100644 > --- a/tools/testing/selftests/riscv/Makefile > +++ b/tools/testing/selftests/riscv/Makefile > @@ -5,7 +5,7 @@ > ARCH ?= $(shell uname -m 2>/dev/null || echo not) > > ifneq (,$(filter $(ARCH),riscv)) > -RISCV_SUBTARGETS ?= hwprobe vector mm > +RISCV_SUBTARGETS ?= hwprobe vector mm sigreturn > else > RISCV_SUBTARGETS := > endif > diff --git a/tools/testing/selftests/riscv/sigreturn/.gitignore b/tools/testing/selftests/riscv/sigreturn/.gitignore > new file mode 100644 > index 000000000000..35002b8ae780 > --- /dev/null > +++ b/tools/testing/selftests/riscv/sigreturn/.gitignore > @@ -0,0 +1 @@ > +sigreturn > diff --git a/tools/testing/selftests/riscv/sigreturn/Makefile b/tools/testing/selftests/riscv/sigreturn/Makefile > new file mode 100644 > index 000000000000..eb8bac9279a8 > --- /dev/null > +++ b/tools/testing/selftests/riscv/sigreturn/Makefile > @@ -0,0 +1,12 @@ > +# SPDX-License-Identifier: GPL-2.0 > +# Copyright (C) 2021 ARM Limited > +# Originally tools/testing/arm64/abi/Makefile > + > +CFLAGS += -I$(top_srcdir)/tools/include > + > +TEST_GEN_PROGS := sigreturn > + > +include ../../lib.mk > + > +$(OUTPUT)/sigreturn: sigreturn.c > + $(CC) -static -o$@ $(CFLAGS) $(LDFLAGS) $^ > diff --git a/tools/testing/selftests/riscv/sigreturn/sigreturn.c b/tools/testing/selftests/riscv/sigreturn/sigreturn.c > new file mode 100644 > index 000000000000..62397d5934f1 > --- /dev/null > +++ b/tools/testing/selftests/riscv/sigreturn/sigreturn.c > @@ -0,0 +1,82 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +#include <signal.h> > +#include <stdio.h> > +#include <stdlib.h> > +#include <ucontext.h> > +#include <linux/ptrace.h> > +#include "../../kselftest_harness.h" > + > +#define RISCV_V_MAGIC 0x53465457 > +#define DEFAULT_VALUE 2 > +#define SIGNAL_HANDLER_OVERRIDE 3 > + > +static void simple_handle(int sig_no, siginfo_t *info, void *vcontext) > +{ > + ucontext_t *context = vcontext; > + > + context->uc_mcontext.__gregs[REG_PC] = context->uc_mcontext.__gregs[REG_PC] + 4; > +} > + > +static void vector_override(int sig_no, siginfo_t *info, void *vcontext) > +{ > + ucontext_t *context = vcontext; > + > + // vector state > + struct __riscv_extra_ext_header *ext; > + struct __riscv_v_ext_state *v_ext_state; > + > + /* Find the vector context. */ > + ext = (void *)(&context->uc_mcontext.__fpregs); > + if (ext->hdr.magic != RISCV_V_MAGIC) { > + fprintf(stderr, "bad vector magic: %x\n", ext->hdr.magic); > + abort(); > + } > + > + v_ext_state = (void *)((char *)(ext) + sizeof(*ext)); > + > + *(int *)v_ext_state->datap = SIGNAL_HANDLER_OVERRIDE; > + > + context->uc_mcontext.__gregs[REG_PC] = context->uc_mcontext.__gregs[REG_PC] + 4; > +} > + > +static int vector_sigreturn(int data, void (*handler)(int, siginfo_t *, void *)) > +{ > + int after_sigreturn; > + struct sigaction sig_action = { > + .sa_sigaction = handler, > + .sa_flags = SA_SIGINFO > + }; > + > + sigaction(SIGSEGV, &sig_action, 0); > + > + asm(".option push \n\ > + .option arch, +v \n\ > + vsetivli x0, 1, e32, ta, ma \n\ > + vmv.s.x v0, %1 \n\ > + # Generate SIGSEGV \n\ > + lw a0, 0(x0) \n\ > + vmv.x.s %0, v0 \n\ > + .option pop" : "=r" (after_sigreturn) : "r" (data)); > + > + return after_sigreturn; > +} > + > +TEST(vector_restore) > +{ > + int result; > + > + result = vector_sigreturn(DEFAULT_VALUE, &simple_handle); > + > + EXPECT_EQ(DEFAULT_VALUE, result); > +} > + > +TEST(vector_restore_signal_handler_override) > +{ > + int result; > + > + result = vector_sigreturn(DEFAULT_VALUE, &vector_override); > + > + EXPECT_EQ(SIGNAL_HANDLER_OVERRIDE, result); > +} > + > +TEST_HARNESS_MAIN > > --- > base-commit: 4cece764965020c22cff7665b18a012006359095 > change-id: 20240403-vector_sigreturn_tests-8118f0ac54fa ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] riscv: selftests: Add signal handling vector tests 2024-04-04 0:27 ` Vineet Gupta @ 2024-04-04 0:43 ` Charlie Jenkins 0 siblings, 0 replies; 7+ messages in thread From: Charlie Jenkins @ 2024-04-04 0:43 UTC (permalink / raw) To: Vineet Gupta Cc: Shuah Khan, Paul Walmsley, Palmer Dabbelt, Albert Ou, Andy Chiu, Björn Töpel, linux-kernel, linux-kselftest, linux-riscv On Wed, Apr 03, 2024 at 05:27:23PM -0700, Vineet Gupta wrote: > On 4/3/24 16:50, Charlie Jenkins wrote: > > Add two tests to check vector save/restore when a signal is received > > during a vector routine. One test ensures that a value is not clobbered > > during signal handling. The other verifies that vector registers > > modified in the signal handler are properly reflected when the signal > > handling is complete. > > Hmm, isn't this testing two contradictory things ? > > We do want V regs to be not clobbered across a handled signal, o/w V > enabled code would just not work at all. > That implies that anything done by signal handler should just be > discarded - no ? > > Am I missing something. > > -Vineet This is referring to the user-implemented signal handler. The test in question is testing the ability of the user-implemented signal handler to be able to modify the vector registers. In the test: static void vector_override(int sig_no, siginfo_t *info, void *vcontext) { ... *(int *)v_ext_state->datap = SIGNAL_HANDLER_OVERRIDE; ... } This line is changing the saved state of the user program's vector registers. When the signal handling concludes and the original user program resumes execution, the content of the user-context registers that were modified by the signal handler should be restored into the hardware registers. Hence the test case checks that the v0 register contains the value SIGNAL_HANDLER_OVERRIDE. EXPECT_EQ(SIGNAL_HANDLER_OVERRIDE, result); - Charlie > > > > > Signed-off-by: Charlie Jenkins <charlie@rivosinc.com> > > --- > > These tests came about to highlight the bug fixed in > > https://lore.kernel.org/lkml/20240403072638.567446-1-bjorn@kernel.org/ > > and will only pass with that fix applied. > > --- > > tools/testing/selftests/riscv/Makefile | 2 +- > > tools/testing/selftests/riscv/sigreturn/.gitignore | 1 + > > tools/testing/selftests/riscv/sigreturn/Makefile | 12 ++++ > > .../testing/selftests/riscv/sigreturn/sigreturn.c | 82 ++++++++++++++++++++++ > > 4 files changed, 96 insertions(+), 1 deletion(-) > > > > diff --git a/tools/testing/selftests/riscv/Makefile b/tools/testing/selftests/riscv/Makefile > > index 4a9ff515a3a0..7ce03d832b64 100644 > > --- a/tools/testing/selftests/riscv/Makefile > > +++ b/tools/testing/selftests/riscv/Makefile > > @@ -5,7 +5,7 @@ > > ARCH ?= $(shell uname -m 2>/dev/null || echo not) > > > > ifneq (,$(filter $(ARCH),riscv)) > > -RISCV_SUBTARGETS ?= hwprobe vector mm > > +RISCV_SUBTARGETS ?= hwprobe vector mm sigreturn > > else > > RISCV_SUBTARGETS := > > endif > > diff --git a/tools/testing/selftests/riscv/sigreturn/.gitignore b/tools/testing/selftests/riscv/sigreturn/.gitignore > > new file mode 100644 > > index 000000000000..35002b8ae780 > > --- /dev/null > > +++ b/tools/testing/selftests/riscv/sigreturn/.gitignore > > @@ -0,0 +1 @@ > > +sigreturn > > diff --git a/tools/testing/selftests/riscv/sigreturn/Makefile b/tools/testing/selftests/riscv/sigreturn/Makefile > > new file mode 100644 > > index 000000000000..eb8bac9279a8 > > --- /dev/null > > +++ b/tools/testing/selftests/riscv/sigreturn/Makefile > > @@ -0,0 +1,12 @@ > > +# SPDX-License-Identifier: GPL-2.0 > > +# Copyright (C) 2021 ARM Limited > > +# Originally tools/testing/arm64/abi/Makefile > > + > > +CFLAGS += -I$(top_srcdir)/tools/include > > + > > +TEST_GEN_PROGS := sigreturn > > + > > +include ../../lib.mk > > + > > +$(OUTPUT)/sigreturn: sigreturn.c > > + $(CC) -static -o$@ $(CFLAGS) $(LDFLAGS) $^ > > diff --git a/tools/testing/selftests/riscv/sigreturn/sigreturn.c b/tools/testing/selftests/riscv/sigreturn/sigreturn.c > > new file mode 100644 > > index 000000000000..62397d5934f1 > > --- /dev/null > > +++ b/tools/testing/selftests/riscv/sigreturn/sigreturn.c > > @@ -0,0 +1,82 @@ > > +// SPDX-License-Identifier: GPL-2.0-only > > +#include <signal.h> > > +#include <stdio.h> > > +#include <stdlib.h> > > +#include <ucontext.h> > > +#include <linux/ptrace.h> > > +#include "../../kselftest_harness.h" > > + > > +#define RISCV_V_MAGIC 0x53465457 > > +#define DEFAULT_VALUE 2 > > +#define SIGNAL_HANDLER_OVERRIDE 3 > > + > > +static void simple_handle(int sig_no, siginfo_t *info, void *vcontext) > > +{ > > + ucontext_t *context = vcontext; > > + > > + context->uc_mcontext.__gregs[REG_PC] = context->uc_mcontext.__gregs[REG_PC] + 4; > > +} > > + > > +static void vector_override(int sig_no, siginfo_t *info, void *vcontext) > > +{ > > + ucontext_t *context = vcontext; > > + > > + // vector state > > + struct __riscv_extra_ext_header *ext; > > + struct __riscv_v_ext_state *v_ext_state; > > + > > + /* Find the vector context. */ > > + ext = (void *)(&context->uc_mcontext.__fpregs); > > + if (ext->hdr.magic != RISCV_V_MAGIC) { > > + fprintf(stderr, "bad vector magic: %x\n", ext->hdr.magic); > > + abort(); > > + } > > + > > + v_ext_state = (void *)((char *)(ext) + sizeof(*ext)); > > + > > + *(int *)v_ext_state->datap = SIGNAL_HANDLER_OVERRIDE; > > + > > + context->uc_mcontext.__gregs[REG_PC] = context->uc_mcontext.__gregs[REG_PC] + 4; > > +} > > + > > +static int vector_sigreturn(int data, void (*handler)(int, siginfo_t *, void *)) > > +{ > > + int after_sigreturn; > > + struct sigaction sig_action = { > > + .sa_sigaction = handler, > > + .sa_flags = SA_SIGINFO > > + }; > > + > > + sigaction(SIGSEGV, &sig_action, 0); > > + > > + asm(".option push \n\ > > + .option arch, +v \n\ > > + vsetivli x0, 1, e32, ta, ma \n\ > > + vmv.s.x v0, %1 \n\ > > + # Generate SIGSEGV \n\ > > + lw a0, 0(x0) \n\ > > + vmv.x.s %0, v0 \n\ > > + .option pop" : "=r" (after_sigreturn) : "r" (data)); > > + > > + return after_sigreturn; > > +} > > + > > +TEST(vector_restore) > > +{ > > + int result; > > + > > + result = vector_sigreturn(DEFAULT_VALUE, &simple_handle); > > + > > + EXPECT_EQ(DEFAULT_VALUE, result); > > +} > > + > > +TEST(vector_restore_signal_handler_override) > > +{ > > + int result; > > + > > + result = vector_sigreturn(DEFAULT_VALUE, &vector_override); > > + > > + EXPECT_EQ(SIGNAL_HANDLER_OVERRIDE, result); > > +} > > + > > +TEST_HARNESS_MAIN > > > > --- > > base-commit: 4cece764965020c22cff7665b18a012006359095 > > change-id: 20240403-vector_sigreturn_tests-8118f0ac54fa > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] riscv: selftests: Add signal handling vector tests 2024-04-03 23:50 [PATCH] riscv: selftests: Add signal handling vector tests Charlie Jenkins 2024-04-04 0:27 ` Vineet Gupta @ 2024-04-04 5:46 ` Björn Töpel 2024-04-09 3:01 ` Andy Chiu 2024-05-22 16:40 ` Palmer Dabbelt 2024-05-22 23:51 ` patchwork-bot+linux-riscv 3 siblings, 1 reply; 7+ messages in thread From: Björn Töpel @ 2024-04-04 5:46 UTC (permalink / raw) To: Charlie Jenkins, Shuah Khan, Paul Walmsley, Palmer Dabbelt, Albert Ou, Andy Chiu, Vineet Gupta Cc: linux-kernel, linux-kselftest, linux-riscv, Charlie Jenkins Charlie Jenkins <charlie@rivosinc.com> writes: > Add two tests to check vector save/restore when a signal is received > during a vector routine. One test ensures that a value is not clobbered > during signal handling. The other verifies that vector registers > modified in the signal handler are properly reflected when the signal > handling is complete. > > Signed-off-by: Charlie Jenkins <charlie@rivosinc.com> Nice! Reviewed-by: Björn Töpel <bjorn@rivosinc.com> ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] riscv: selftests: Add signal handling vector tests 2024-04-04 5:46 ` Björn Töpel @ 2024-04-09 3:01 ` Andy Chiu 0 siblings, 0 replies; 7+ messages in thread From: Andy Chiu @ 2024-04-09 3:01 UTC (permalink / raw) To: Björn Töpel Cc: Charlie Jenkins, Shuah Khan, Paul Walmsley, Palmer Dabbelt, Albert Ou, Vineet Gupta, linux-kernel, linux-kselftest, linux-riscv On Thu, Apr 4, 2024 at 1:47 PM Björn Töpel <bjorn@kernel.org> wrote: > > Charlie Jenkins <charlie@rivosinc.com> writes: > > > Add two tests to check vector save/restore when a signal is received > > during a vector routine. One test ensures that a value is not clobbered > > during signal handling. The other verifies that vector registers > > modified in the signal handler are properly reflected when the signal > > handling is complete. > > > > Signed-off-by: Charlie Jenkins <charlie@rivosinc.com> > > Nice! > > Reviewed-by: Björn Töpel <bjorn@rivosinc.com> Thanks! Reviewed-by: Andy Chiu <andy.chiu@sifive.com> Tested-by: Andy Chiu <andy.chiu@sifive.com> ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] riscv: selftests: Add signal handling vector tests 2024-04-03 23:50 [PATCH] riscv: selftests: Add signal handling vector tests Charlie Jenkins 2024-04-04 0:27 ` Vineet Gupta 2024-04-04 5:46 ` Björn Töpel @ 2024-05-22 16:40 ` Palmer Dabbelt 2024-05-22 23:51 ` patchwork-bot+linux-riscv 3 siblings, 0 replies; 7+ messages in thread From: Palmer Dabbelt @ 2024-05-22 16:40 UTC (permalink / raw) To: Charlie Jenkins Cc: shuah, Paul Walmsley, aou, andy.chiu, bjorn, Vineet Gupta, linux-kernel, linux-kselftest, linux-riscv, Charlie Jenkins On Wed, 03 Apr 2024 16:50:29 PDT (-0700), Charlie Jenkins wrote: > Add two tests to check vector save/restore when a signal is received > during a vector routine. One test ensures that a value is not clobbered > during signal handling. The other verifies that vector registers > modified in the signal handler are properly reflected when the signal > handling is complete. > > Signed-off-by: Charlie Jenkins <charlie@rivosinc.com> > --- > These tests came about to highlight the bug fixed in > https://lore.kernel.org/lkml/20240403072638.567446-1-bjorn@kernel.org/ > and will only pass with that fix applied. Thaks. I'm just staging this, I have a testcase too that I keep forgetting to post because I haven't gotten in into the selftests sanely yet... #include "../../kselftest.h" #include <signal.h> #include <stdlib.h> #include <asm/ptrace.h> #include <stdint.h> #define ITERATIONS (1 << 24) #define RISCV_V_MAGIC 0x53465457 struct __riscv_ctx_hdr { __u32 magic; __u32 size; }; struct __riscv_extra_ext_header { __u32 __padding[129] __attribute__((aligned(16))); /* * Reserved for expansion of sigcontext structure. Currently zeroed * upon signal, and must be zero upon sigreturn. */ __u32 reserved; struct __riscv_ctx_hdr hdr; }; struct __riscv_v_ext_state { unsigned long vstart; unsigned long vl; unsigned long vtype; unsigned long vcsr; unsigned long vlenb; void *datap; /* * In signal handler, datap will be set a correct user stack offset * and vector registers will be copied to the address of datap * pointer. */ }; /* The beginning of the actual state. */ int count; void handler(int, siginfo_t *si, void *ucontext_void) { ucontext_t *ucontext = ucontext_void; /* Skip over the SEGV by just jumping to a0. */ ucontext->uc_mcontext.__gregs[REG_PC] = ucontext->uc_mcontext.__gregs[REG_A0]; /* Increment the first element of v0. */ { struct __riscv_extra_ext_header *ext; struct __riscv_v_ext_state *v_ext_state; uint32_t val; /* Find the vector context. */ ext = (void *)(&ucontext->uc_mcontext.__fpregs); if (ext->hdr.magic != RISCV_V_MAGIC) { fprintf(stderr, "bad vector magic: %x\n", ext->hdr.magic); abort(); } v_ext_state = (void *)((char *)(ext) + sizeof(*ext)); /* Actually do the increment. */ memcpy(&val, v_ext_state->datap, sizeof(val)); val++; memcpy(v_ext_state->datap, &val, sizeof(val)); } /* Count the delivered signal, to make sure we don't miss any. */ count++; } void sigill(int, siginfo_t *si, void *ucontext_void) { fprintf(stderr, "SIGILL after %d iterations\n", count); abort(); } void check_signal(void) { int check = rand(); int out; __asm__ volatile ( "vsetvli a0, %2, e32, ta, ma\n\t" "vmv.s.x v0, %1\n\t" "la a0, 1f\n\t" "lw t0, 0(x0)\n\t" "1:\n\t" "vmv.x.s %0, v0" : "=&r"(out) : "r"(check-1), "r"(1) : "a0" #ifdef __riscv_vector , "v0" #endif ); if (out != check) { fprintf(stderr, "out: %d\ncheck: %d\n", out, check); abort(); } } int main(void) { struct sigaction sa_segv, sa_ill; memset(&sa_segv, 0, sizeof(sa_segv)); sa_segv.sa_sigaction = &handler; sa_segv.sa_flags = SA_SIGINFO; sigaction(SIGSEGV, &sa_segv, NULL); memset(&sa_ill, 0, sizeof(sa_ill)); sa_ill.sa_sigaction = &sigill; sa_ill.sa_flags = SA_SIGINFO; sigaction(SIGILL, &sa_ill, NULL); count = 0; for (int i = 0; i < ITERATIONS; ++i) check_signal(); if (count != ITERATIONS) { fprintf(stderr, "count: %d\n", count); abort(); } return 0; } > --- > tools/testing/selftests/riscv/Makefile | 2 +- > tools/testing/selftests/riscv/sigreturn/.gitignore | 1 + > tools/testing/selftests/riscv/sigreturn/Makefile | 12 ++++ > .../testing/selftests/riscv/sigreturn/sigreturn.c | 82 ++++++++++++++++++++++ > 4 files changed, 96 insertions(+), 1 deletion(-) > > diff --git a/tools/testing/selftests/riscv/Makefile b/tools/testing/selftests/riscv/Makefile > index 4a9ff515a3a0..7ce03d832b64 100644 > --- a/tools/testing/selftests/riscv/Makefile > +++ b/tools/testing/selftests/riscv/Makefile > @@ -5,7 +5,7 @@ > ARCH ?= $(shell uname -m 2>/dev/null || echo not) > > ifneq (,$(filter $(ARCH),riscv)) > -RISCV_SUBTARGETS ?= hwprobe vector mm > +RISCV_SUBTARGETS ?= hwprobe vector mm sigreturn > else > RISCV_SUBTARGETS := > endif > diff --git a/tools/testing/selftests/riscv/sigreturn/.gitignore b/tools/testing/selftests/riscv/sigreturn/.gitignore > new file mode 100644 > index 000000000000..35002b8ae780 > --- /dev/null > +++ b/tools/testing/selftests/riscv/sigreturn/.gitignore > @@ -0,0 +1 @@ > +sigreturn > diff --git a/tools/testing/selftests/riscv/sigreturn/Makefile b/tools/testing/selftests/riscv/sigreturn/Makefile > new file mode 100644 > index 000000000000..eb8bac9279a8 > --- /dev/null > +++ b/tools/testing/selftests/riscv/sigreturn/Makefile > @@ -0,0 +1,12 @@ > +# SPDX-License-Identifier: GPL-2.0 > +# Copyright (C) 2021 ARM Limited > +# Originally tools/testing/arm64/abi/Makefile > + > +CFLAGS += -I$(top_srcdir)/tools/include > + > +TEST_GEN_PROGS := sigreturn > + > +include ../../lib.mk > + > +$(OUTPUT)/sigreturn: sigreturn.c > + $(CC) -static -o$@ $(CFLAGS) $(LDFLAGS) $^ > diff --git a/tools/testing/selftests/riscv/sigreturn/sigreturn.c b/tools/testing/selftests/riscv/sigreturn/sigreturn.c > new file mode 100644 > index 000000000000..62397d5934f1 > --- /dev/null > +++ b/tools/testing/selftests/riscv/sigreturn/sigreturn.c > @@ -0,0 +1,82 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +#include <signal.h> > +#include <stdio.h> > +#include <stdlib.h> > +#include <ucontext.h> > +#include <linux/ptrace.h> > +#include "../../kselftest_harness.h" > + > +#define RISCV_V_MAGIC 0x53465457 > +#define DEFAULT_VALUE 2 > +#define SIGNAL_HANDLER_OVERRIDE 3 > + > +static void simple_handle(int sig_no, siginfo_t *info, void *vcontext) > +{ > + ucontext_t *context = vcontext; > + > + context->uc_mcontext.__gregs[REG_PC] = context->uc_mcontext.__gregs[REG_PC] + 4; > +} > + > +static void vector_override(int sig_no, siginfo_t *info, void *vcontext) > +{ > + ucontext_t *context = vcontext; > + > + // vector state > + struct __riscv_extra_ext_header *ext; > + struct __riscv_v_ext_state *v_ext_state; > + > + /* Find the vector context. */ > + ext = (void *)(&context->uc_mcontext.__fpregs); > + if (ext->hdr.magic != RISCV_V_MAGIC) { > + fprintf(stderr, "bad vector magic: %x\n", ext->hdr.magic); > + abort(); > + } > + > + v_ext_state = (void *)((char *)(ext) + sizeof(*ext)); > + > + *(int *)v_ext_state->datap = SIGNAL_HANDLER_OVERRIDE; > + > + context->uc_mcontext.__gregs[REG_PC] = context->uc_mcontext.__gregs[REG_PC] + 4; > +} > + > +static int vector_sigreturn(int data, void (*handler)(int, siginfo_t *, void *)) > +{ > + int after_sigreturn; > + struct sigaction sig_action = { > + .sa_sigaction = handler, > + .sa_flags = SA_SIGINFO > + }; > + > + sigaction(SIGSEGV, &sig_action, 0); > + > + asm(".option push \n\ > + .option arch, +v \n\ > + vsetivli x0, 1, e32, ta, ma \n\ > + vmv.s.x v0, %1 \n\ > + # Generate SIGSEGV \n\ > + lw a0, 0(x0) \n\ > + vmv.x.s %0, v0 \n\ > + .option pop" : "=r" (after_sigreturn) : "r" (data)); > + > + return after_sigreturn; > +} > + > +TEST(vector_restore) > +{ > + int result; > + > + result = vector_sigreturn(DEFAULT_VALUE, &simple_handle); > + > + EXPECT_EQ(DEFAULT_VALUE, result); > +} > + > +TEST(vector_restore_signal_handler_override) > +{ > + int result; > + > + result = vector_sigreturn(DEFAULT_VALUE, &vector_override); > + > + EXPECT_EQ(SIGNAL_HANDLER_OVERRIDE, result); > +} > + > +TEST_HARNESS_MAIN > > --- > base-commit: 4cece764965020c22cff7665b18a012006359095 > change-id: 20240403-vector_sigreturn_tests-8118f0ac54fa ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] riscv: selftests: Add signal handling vector tests 2024-04-03 23:50 [PATCH] riscv: selftests: Add signal handling vector tests Charlie Jenkins ` (2 preceding siblings ...) 2024-05-22 16:40 ` Palmer Dabbelt @ 2024-05-22 23:51 ` patchwork-bot+linux-riscv 3 siblings, 0 replies; 7+ messages in thread From: patchwork-bot+linux-riscv @ 2024-05-22 23:51 UTC (permalink / raw) To: Charlie Jenkins Cc: linux-riscv, shuah, paul.walmsley, palmer, aou, andy.chiu, bjorn, vineetg, linux-kernel, linux-kselftest Hello: This patch was applied to riscv/linux.git (for-next) by Palmer Dabbelt <palmer@rivosinc.com>: On Wed, 03 Apr 2024 16:50:29 -0700 you wrote: > Add two tests to check vector save/restore when a signal is received > during a vector routine. One test ensures that a value is not clobbered > during signal handling. The other verifies that vector registers > modified in the signal handler are properly reflected when the signal > handling is complete. > > Signed-off-by: Charlie Jenkins <charlie@rivosinc.com> > > [...] Here is the summary with links: - riscv: selftests: Add signal handling vector tests https://git.kernel.org/riscv/c/b2a2e892cdbc You are awesome, thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2024-05-22 23:51 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-04-03 23:50 [PATCH] riscv: selftests: Add signal handling vector tests Charlie Jenkins 2024-04-04 0:27 ` Vineet Gupta 2024-04-04 0:43 ` Charlie Jenkins 2024-04-04 5:46 ` Björn Töpel 2024-04-09 3:01 ` Andy Chiu 2024-05-22 16:40 ` Palmer Dabbelt 2024-05-22 23:51 ` patchwork-bot+linux-riscv
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox