Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright 2015, Michael Neuling, IBM Corp.
0004  *
0005  * Test the kernel's signal return code to ensure that it doesn't
0006  * crash when both the transactional and suspend MSR bits are set in
0007  * the signal context.
0008  *
0009  * For this test, we send ourselves a SIGUSR1.  In the SIGUSR1 handler
0010  * we modify the signal context to set both MSR TM S and T bits (which
0011  * is "reserved" by the PowerISA). When we return from the signal
0012  * handler (implicit sigreturn), the kernel should detect reserved MSR
0013  * value and send us with a SIGSEGV.
0014  */
0015 
0016 #include <stdlib.h>
0017 #include <stdio.h>
0018 #include <signal.h>
0019 #include <unistd.h>
0020 
0021 #include "utils.h"
0022 #include "tm.h"
0023 
0024 int segv_expected = 0;
0025 
0026 void signal_segv(int signum)
0027 {
0028     if (segv_expected && (signum == SIGSEGV))
0029         _exit(0);
0030     _exit(1);
0031 }
0032 
0033 void signal_usr1(int signum, siginfo_t *info, void *uc)
0034 {
0035     ucontext_t *ucp = uc;
0036 
0037     /* Link tm checkpointed context to normal context */
0038     ucp->uc_link = ucp;
0039     /* Set all TM bits so that the context is now invalid */
0040 #ifdef __powerpc64__
0041     ucp->uc_mcontext.gp_regs[PT_MSR] |= (7ULL << 32);
0042 #else
0043     ucp->uc_mcontext.uc_regs->gregs[PT_MSR] |= (7ULL);
0044 #endif
0045     /* Should segv on return becuase of invalid context */
0046     segv_expected = 1;
0047 }
0048 
0049 int tm_signal_msr_resv()
0050 {
0051     struct sigaction act;
0052 
0053     SKIP_IF(!have_htm());
0054 
0055     act.sa_sigaction = signal_usr1;
0056     sigemptyset(&act.sa_mask);
0057     act.sa_flags = SA_SIGINFO;
0058     if (sigaction(SIGUSR1, &act, NULL) < 0) {
0059         perror("sigaction sigusr1");
0060         exit(1);
0061     }
0062     if (signal(SIGSEGV, signal_segv) == SIG_ERR)
0063         exit(1);
0064 
0065     raise(SIGUSR1);
0066 
0067     /* We shouldn't get here as we exit in the segv handler */
0068     return 1;
0069 }
0070 
0071 int main(void)
0072 {
0073     return test_harness(tm_signal_msr_resv, "tm_signal_msr_resv");
0074 }