Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 9d5328e

Browse files
charlie-rivospalmer-dabbelt
authored andcommitted
riscv: selftests: Add signal handling vector tests
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> Reviewed-by: Björn Töpel <bjorn@rivosinc.com> Reviewed-by: Andy Chiu <andy.chiu@sifive.com> Tested-by: Andy Chiu <andy.chiu@sifive.com> Link: https://lore.kernel.org/r/20240403-vector_sigreturn_tests-v1-1-2e68b7a3b8d7@rivosinc.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
1 parent 4c6c002 commit 9d5328e

File tree

4 files changed

+96
-1
lines changed

4 files changed

+96
-1
lines changed

tools/testing/selftests/riscv/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
ARCH ?= $(shell uname -m 2>/dev/null || echo not)
66

77
ifneq (,$(filter $(ARCH),riscv))
8-
RISCV_SUBTARGETS ?= hwprobe vector mm
8+
RISCV_SUBTARGETS ?= hwprobe vector mm sigreturn
99
else
1010
RISCV_SUBTARGETS :=
1111
endif
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
sigreturn
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
# Copyright (C) 2021 ARM Limited
3+
# Originally tools/testing/arm64/abi/Makefile
4+
5+
CFLAGS += -I$(top_srcdir)/tools/include
6+
7+
TEST_GEN_PROGS := sigreturn
8+
9+
include ../../lib.mk
10+
11+
$(OUTPUT)/sigreturn: sigreturn.c
12+
$(CC) -static -o$@ $(CFLAGS) $(LDFLAGS) $^
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
#include <signal.h>
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <ucontext.h>
6+
#include <linux/ptrace.h>
7+
#include "../../kselftest_harness.h"
8+
9+
#define RISCV_V_MAGIC 0x53465457
10+
#define DEFAULT_VALUE 2
11+
#define SIGNAL_HANDLER_OVERRIDE 3
12+
13+
static void simple_handle(int sig_no, siginfo_t *info, void *vcontext)
14+
{
15+
ucontext_t *context = vcontext;
16+
17+
context->uc_mcontext.__gregs[REG_PC] = context->uc_mcontext.__gregs[REG_PC] + 4;
18+
}
19+
20+
static void vector_override(int sig_no, siginfo_t *info, void *vcontext)
21+
{
22+
ucontext_t *context = vcontext;
23+
24+
// vector state
25+
struct __riscv_extra_ext_header *ext;
26+
struct __riscv_v_ext_state *v_ext_state;
27+
28+
/* Find the vector context. */
29+
ext = (void *)(&context->uc_mcontext.__fpregs);
30+
if (ext->hdr.magic != RISCV_V_MAGIC) {
31+
fprintf(stderr, "bad vector magic: %x\n", ext->hdr.magic);
32+
abort();
33+
}
34+
35+
v_ext_state = (void *)((char *)(ext) + sizeof(*ext));
36+
37+
*(int *)v_ext_state->datap = SIGNAL_HANDLER_OVERRIDE;
38+
39+
context->uc_mcontext.__gregs[REG_PC] = context->uc_mcontext.__gregs[REG_PC] + 4;
40+
}
41+
42+
static int vector_sigreturn(int data, void (*handler)(int, siginfo_t *, void *))
43+
{
44+
int after_sigreturn;
45+
struct sigaction sig_action = {
46+
.sa_sigaction = handler,
47+
.sa_flags = SA_SIGINFO
48+
};
49+
50+
sigaction(SIGSEGV, &sig_action, 0);
51+
52+
asm(".option push \n\
53+
.option arch, +v \n\
54+
vsetivli x0, 1, e32, ta, ma \n\
55+
vmv.s.x v0, %1 \n\
56+
# Generate SIGSEGV \n\
57+
lw a0, 0(x0) \n\
58+
vmv.x.s %0, v0 \n\
59+
.option pop" : "=r" (after_sigreturn) : "r" (data));
60+
61+
return after_sigreturn;
62+
}
63+
64+
TEST(vector_restore)
65+
{
66+
int result;
67+
68+
result = vector_sigreturn(DEFAULT_VALUE, &simple_handle);
69+
70+
EXPECT_EQ(DEFAULT_VALUE, result);
71+
}
72+
73+
TEST(vector_restore_signal_handler_override)
74+
{
75+
int result;
76+
77+
result = vector_sigreturn(DEFAULT_VALUE, &vector_override);
78+
79+
EXPECT_EQ(SIGNAL_HANDLER_OVERRIDE, result);
80+
}
81+
82+
TEST_HARNESS_MAIN

0 commit comments

Comments
 (0)