1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright 2016, Cyril Bur, IBM Corp. 4 * 5 * Sending one self a signal should always get delivered. 6 */ 7 8 #include <errno.h> 9 #include <stdlib.h> 10 #include <stdio.h> 11 #include <string.h> 12 #include <signal.h> 13 #include <unistd.h> 14 15 #include <altivec.h> 16 17 #include "utils.h" 18 #include "../tm/tm.h" 19 20 #define MAX_ATTEMPT 500000 21 #define TIMEOUT 10 22 23 extern long tm_signal_self(pid_t pid, int sig, long *ret); 24 25 static sig_atomic_t signaled; 26 static sig_atomic_t fail; 27 28 static void signal_handler(int sig) 29 { 30 if (tcheck_active()) { 31 fail = 2; 32 return; 33 } 34 35 if (sig == SIGUSR1) 36 signaled = 1; 37 else 38 fail = 1; 39 } 40 41 static int test_signal_tm() 42 { 43 int i; 44 struct sigaction act; 45 46 act.sa_handler = signal_handler; 47 act.sa_flags = 0; 48 sigemptyset(&act.sa_mask); 49 if (sigaction(SIGUSR1, &act, NULL) < 0) { 50 perror("sigaction SIGUSR1"); 51 exit(1); 52 } 53 if (sigaction(SIGALRM, &act, NULL) < 0) { 54 perror("sigaction SIGALRM"); 55 exit(1); 56 } 57 58 SKIP_IF(!have_htm()); 59 60 for (i = 0; i < MAX_ATTEMPT; i++) { 61 /* 62 * If anything bad happens in ASM and we fail to set ret 63 * because *handwave* TM this will cause failure 64 */ 65 long ret = 0xdead; 66 long rc = 0xbeef; 67 68 alarm(0); /* Disable any pending */ 69 signaled = 0; 70 alarm(TIMEOUT); 71 FAIL_IF(tcheck_transactional()); 72 rc = tm_signal_self(getpid(), SIGUSR1, &ret); 73 if (ret == 0xdead) 74 /* 75 * This basically means the transaction aborted before we 76 * even got to the suspend... this is crazy but it 77 * happens. 78 * Yes this also means we might never make forward 79 * progress... the alarm() will trip eventually... 80 */ 81 continue; 82 83 if (rc || ret) { 84 /* Ret is actually an errno */ 85 printf("TEXASR 0x%016lx, TFIAR 0x%016lx\n", 86 __builtin_get_texasr(), __builtin_get_tfiar()); 87 fprintf(stderr, "(%d) Fail reason: %d rc=0x%lx ret=0x%lx\n", 88 i, fail, rc, ret); 89 FAIL_IF(ret); 90 } 91 while(!signaled && !fail) 92 asm volatile("": : :"memory"); 93 if (!signaled) { 94 fprintf(stderr, "(%d) Fail reason: %d rc=0x%lx ret=0x%lx\n", 95 i, fail, rc, ret); 96 FAIL_IF(fail); /* For the line number */ 97 } 98 } 99 100 return 0; 101 } 102 103 int main(void) 104 { 105 return test_harness(test_signal_tm, "signal_tm"); 106 } 107