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 SKIP_IF(htm_is_synthetic()); 60 61 for (i = 0; i < MAX_ATTEMPT; i++) { 62 /* 63 * If anything bad happens in ASM and we fail to set ret 64 * because *handwave* TM this will cause failure 65 */ 66 long ret = 0xdead; 67 long rc = 0xbeef; 68 69 alarm(0); /* Disable any pending */ 70 signaled = 0; 71 alarm(TIMEOUT); 72 FAIL_IF(tcheck_transactional()); 73 rc = tm_signal_self(getpid(), SIGUSR1, &ret); 74 if (ret == 0xdead) 75 /* 76 * This basically means the transaction aborted before we 77 * even got to the suspend... this is crazy but it 78 * happens. 79 * Yes this also means we might never make forward 80 * progress... the alarm() will trip eventually... 81 */ 82 continue; 83 84 if (rc || ret) { 85 /* Ret is actually an errno */ 86 printf("TEXASR 0x%016lx, TFIAR 0x%016lx\n", 87 __builtin_get_texasr(), __builtin_get_tfiar()); 88 fprintf(stderr, "(%d) Fail reason: %d rc=0x%lx ret=0x%lx\n", 89 i, fail, rc, ret); 90 FAIL_IF(ret); 91 } 92 while(!signaled && !fail) 93 asm volatile("": : :"memory"); 94 if (!signaled) { 95 fprintf(stderr, "(%d) Fail reason: %d rc=0x%lx ret=0x%lx\n", 96 i, fail, rc, ret); 97 FAIL_IF(fail); /* For the line number */ 98 } 99 } 100 101 return 0; 102 } 103 104 int main(void) 105 { 106 return test_harness(test_signal_tm, "signal_tm"); 107 } 108