root/tools/testing/selftests/powerpc/tm/tm-signal-msr-resv.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. signal_segv
  2. signal_usr1
  3. tm_signal_msr_resv
  4. main

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright 2015, Michael Neuling, IBM Corp.
   4  *
   5  * Test the kernel's signal return code to ensure that it doesn't
   6  * crash when both the transactional and suspend MSR bits are set in
   7  * the signal context.
   8  *
   9  * For this test, we send ourselves a SIGUSR1.  In the SIGUSR1 handler
  10  * we modify the signal context to set both MSR TM S and T bits (which
  11  * is "reserved" by the PowerISA). When we return from the signal
  12  * handler (implicit sigreturn), the kernel should detect reserved MSR
  13  * value and send us with a SIGSEGV.
  14  */
  15 
  16 #include <stdlib.h>
  17 #include <stdio.h>
  18 #include <signal.h>
  19 #include <unistd.h>
  20 
  21 #include "utils.h"
  22 #include "tm.h"
  23 
  24 int segv_expected = 0;
  25 
  26 void signal_segv(int signum)
  27 {
  28         if (segv_expected && (signum == SIGSEGV))
  29                 _exit(0);
  30         _exit(1);
  31 }
  32 
  33 void signal_usr1(int signum, siginfo_t *info, void *uc)
  34 {
  35         ucontext_t *ucp = uc;
  36 
  37         /* Link tm checkpointed context to normal context */
  38         ucp->uc_link = ucp;
  39         /* Set all TM bits so that the context is now invalid */
  40 #ifdef __powerpc64__
  41         ucp->uc_mcontext.gp_regs[PT_MSR] |= (7ULL << 32);
  42 #else
  43         ucp->uc_mcontext.uc_regs->gregs[PT_MSR] |= (7ULL);
  44 #endif
  45         /* Should segv on return becuase of invalid context */
  46         segv_expected = 1;
  47 }
  48 
  49 int tm_signal_msr_resv()
  50 {
  51         struct sigaction act;
  52 
  53         SKIP_IF(!have_htm());
  54 
  55         act.sa_sigaction = signal_usr1;
  56         sigemptyset(&act.sa_mask);
  57         act.sa_flags = SA_SIGINFO;
  58         if (sigaction(SIGUSR1, &act, NULL) < 0) {
  59                 perror("sigaction sigusr1");
  60                 exit(1);
  61         }
  62         if (signal(SIGSEGV, signal_segv) == SIG_ERR)
  63                 exit(1);
  64 
  65         raise(SIGUSR1);
  66 
  67         /* We shouldn't get here as we exit in the segv handler */
  68         return 1;
  69 }
  70 
  71 int main(void)
  72 {
  73         return test_harness(tm_signal_msr_resv, "tm_signal_msr_resv");
  74 }

/* [<][>][^][v][top][bottom][index][help] */