aboutsummaryrefslogtreecommitdiffstats
path: root/tools/testing/selftests/arm64/signal/test_signals_utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/testing/selftests/arm64/signal/test_signals_utils.c')
-rw-r--r--tools/testing/selftests/arm64/signal/test_signals_utils.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.c b/tools/testing/selftests/arm64/signal/test_signals_utils.c
index 76eaa505a789..2de6e5ed5e25 100644
--- a/tools/testing/selftests/arm64/signal/test_signals_utils.c
+++ b/tools/testing/selftests/arm64/signal/test_signals_utils.c
@@ -11,14 +11,19 @@
#include <linux/auxvec.h>
#include <ucontext.h>
+#include <asm/unistd.h>
+
#include <kselftest.h>
#include "test_signals.h"
#include "test_signals_utils.h"
#include "testcases/testcases.h"
+
extern struct tdescr *current;
+static int sig_copyctx = SIGTRAP;
+
static char const *const feats_names[FMAX_END] = {
" SSBS ",
};
@@ -154,6 +159,20 @@ static bool handle_signal_ok(struct tdescr *td,
return true;
}
+static bool handle_signal_copyctx(struct tdescr *td,
+ siginfo_t *si, void *uc)
+{
+ /* Mangling PC to avoid loops on original BRK instr */
+ ((ucontext_t *)uc)->uc_mcontext.pc += 4;
+ memcpy(td->live_uc, uc, td->live_sz);
+ ASSERT_GOOD_CONTEXT(td->live_uc);
+ td->live_uc_valid = 1;
+ fprintf(stderr,
+ "GOOD CONTEXT grabbed from sig_copyctx handler\n");
+
+ return true;
+}
+
static void default_handler(int signum, siginfo_t *si, void *uc)
{
if (current->sig_unsupp && signum == current->sig_unsupp &&
@@ -165,6 +184,9 @@ static void default_handler(int signum, siginfo_t *si, void *uc)
} else if (current->sig_ok && signum == current->sig_ok &&
handle_signal_ok(current, si, uc)) {
fprintf(stderr, "Handled SIG_OK\n");
+ } else if (signum == sig_copyctx && current->live_uc &&
+ handle_signal_copyctx(current, si, uc)) {
+ fprintf(stderr, "Handled SIG_COPYCTX\n");
} else {
if (signum == SIGALRM && current->timeout) {
fprintf(stderr, "-- Timeout !\n");
@@ -219,6 +241,15 @@ static inline int default_trigger(struct tdescr *td)
int test_init(struct tdescr *td)
{
+ if (td->sig_trig == sig_copyctx) {
+ fprintf(stdout,
+ "Signal %d is RESERVED, cannot be used as a trigger. Aborting\n",
+ sig_copyctx);
+ return 0;
+ }
+ /* just in case */
+ unblock_signal(sig_copyctx);
+
td->minsigstksz = getauxval(AT_MINSIGSTKSZ);
if (!td->minsigstksz)
td->minsigstksz = MINSIGSTKSZ;