kselftest: arm64: add helper get_current_context
[linux-2.6-microblaze.git] / tools / testing / selftests / arm64 / signal / test_signals_utils.c
index 76eaa50..2de6e5e 100644 (file)
 #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;