aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorMichael Neuling <mikey@neuling.org>2015-11-19 23:15:33 -0500
committerMichael Ellerman <mpe@ellerman.id.au>2015-12-14 04:41:48 -0500
commit25007a69e852389985ee98235e76d740d4821c6c (patch)
tree16dd7664889f9bcec4d30fafe234a32a734520cc /tools
parentb319ee8445961c5f7b2fd199c0ef99c418ee2d4a (diff)
selftests/powerpc: Add TM signal return test
Test the kernel's signal return code to ensure that it doesn't crash when both the transactional and suspend MSR bits are set in the signal context. Signed-off-by: Michael Neuling <mikey@neuling.org> Tested-by: Anshuman Khandual <khandual@linux.vnet.ibm.com> [mpe: Skip if we don't have TM] Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'tools')
-rw-r--r--tools/testing/selftests/powerpc/tm/.gitignore1
-rw-r--r--tools/testing/selftests/powerpc/tm/Makefile2
-rw-r--r--tools/testing/selftests/powerpc/tm/tm-signal-msr-resv.c74
3 files changed, 76 insertions, 1 deletions
diff --git a/tools/testing/selftests/powerpc/tm/.gitignore b/tools/testing/selftests/powerpc/tm/.gitignore
index 2699635d2cd9..61c318fdace4 100644
--- a/tools/testing/selftests/powerpc/tm/.gitignore
+++ b/tools/testing/selftests/powerpc/tm/.gitignore
@@ -1,2 +1,3 @@
1tm-resched-dscr 1tm-resched-dscr
2tm-syscall 2tm-syscall
3tm-signal-msr-resv
diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile
index 63b55d01da35..c6b4ca8b2812 100644
--- a/tools/testing/selftests/powerpc/tm/Makefile
+++ b/tools/testing/selftests/powerpc/tm/Makefile
@@ -1,4 +1,4 @@
1TEST_PROGS := tm-resched-dscr tm-syscall 1TEST_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv
2 2
3all: $(TEST_PROGS) 3all: $(TEST_PROGS)
4 4
diff --git a/tools/testing/selftests/powerpc/tm/tm-signal-msr-resv.c b/tools/testing/selftests/powerpc/tm/tm-signal-msr-resv.c
new file mode 100644
index 000000000000..d86653f282b1
--- /dev/null
+++ b/tools/testing/selftests/powerpc/tm/tm-signal-msr-resv.c
@@ -0,0 +1,74 @@
1/*
2 * Copyright 2015, Michael Neuling, IBM Corp.
3 * Licensed under GPLv2.
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
24int segv_expected = 0;
25
26void signal_segv(int signum)
27{
28 if (segv_expected && (signum == SIGSEGV))
29 _exit(0);
30 _exit(1);
31}
32
33void 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.regs->gpr[PT_MSR] |= (7ULL);
44#endif
45 /* Should segv on return becuase of invalid context */
46 segv_expected = 1;
47}
48
49int 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
71int main(void)
72{
73 return test_harness(tm_signal_msr_resv, "tm_signal_msr_resv");
74}