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 SKIP_IF(!is_ppc64le()); 59 60 memset(&sa, 0, sizeof(sa)); 61 sa.sa_handler = handler; 62 sigemptyset(&sa.sa_mask); 63 64 if (sigaction(SIGSEGV, &sa, NULL)) 65 exit(1); 66 67 asm __volatile__( 68 "tbegin. ;" 69 "beq 1f ;" 70 "li 3,0 ;" 71 "std 3,0(3) ;" /* trigger SEGV */ 72 "li 3,1 ;" 73 "std%X[ret] 3,%[ret] ;" 74 "tend. ;" 75 "b 2f ;" 76 "1: ;" 77 "li 3,2 ;" 78 "std%X[ret] 3,%[ret] ;" 79 "2: ;" 80 : [ret] "=m"(ret) 81 : 82 : "memory", "3", "cr0"); 83 84 if (ret != 2) 85 exit(1); 86 87 exit(0); 88 } 89 90 int main(void) 91 { 92 return test_harness(tm_sigreturn, "tm_sigreturn"); 93 } 94