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 } 93