]> asedeno.scripts.mit.edu Git - linux.git/blob - tools/testing/selftests/powerpc/tm/tm-sigreturn.c
Merge tag 'powerpc-4.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
[linux.git] / tools / testing / selftests / powerpc / tm / tm-sigreturn.c
1 // SPDX-License-Identifier: GPL-2.0
2
3 /*
4  * Copyright 2015, Laurent Dufour, IBM Corp.
5  *
6  * Test the kernel's signal returning code to check reclaim is done if the
7  * sigreturn() is called while in a transaction (suspended since active is
8  * already dropped trough the system call path).
9  *
10  * The kernel must discard the transaction when entering sigreturn, since
11  * restoring the potential TM SPRS from the signal frame is requiring to not be
12  * in a transaction.
13  */
14
15 #include <signal.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <sys/types.h>
20 #include <sys/wait.h>
21 #include <unistd.h>
22
23 #include "tm.h"
24 #include "utils.h"
25
26
27 void handler(int sig)
28 {
29         uint64_t ret;
30
31         asm __volatile__(
32                 "li             3,1             ;"
33                 "tbegin.                        ;"
34                 "beq            1f              ;"
35                 "li             3,0             ;"
36                 "tsuspend.                      ;"
37                 "1:                             ;"
38                 "std%X[ret]     3, %[ret]       ;"
39                 : [ret] "=m"(ret)
40                 :
41                 : "memory", "3", "cr0");
42
43         if (ret)
44                 exit(1);
45
46         /*
47          * We return from the signal handle while in a suspended transaction
48          */
49 }
50
51
52 int tm_sigreturn(void)
53 {
54         struct sigaction sa;
55         uint64_t ret = 0;
56
57         SKIP_IF(!have_htm());
58
59         memset(&sa, 0, sizeof(sa));
60         sa.sa_handler = handler;
61         sigemptyset(&sa.sa_mask);
62
63         if (sigaction(SIGSEGV, &sa, NULL))
64                 exit(1);
65
66         asm __volatile__(
67                 "tbegin.                        ;"
68                 "beq            1f              ;"
69                 "li             3,0             ;"
70                 "std            3,0(3)          ;" /* trigger SEGV */
71                 "li             3,1             ;"
72                 "std%X[ret]     3,%[ret]        ;"
73                 "tend.                          ;"
74                 "b              2f              ;"
75                 "1:                             ;"
76                 "li             3,2             ;"
77                 "std%X[ret]     3,%[ret]        ;"
78                 "2:                             ;"
79                 : [ret] "=m"(ret)
80                 :
81                 : "memory", "3", "cr0");
82
83         if (ret != 2)
84                 exit(1);
85
86         exit(0);
87 }
88
89 int main(void)
90 {
91         return test_harness(tm_sigreturn, "tm_sigreturn");
92 }