1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright 2016, Cyril Bur, IBM Corp. 4 * 5 * Test the kernel's signal frame code. 6 * 7 * The kernel sets up two sets of ucontexts if the signal was to be 8 * delivered while the thread was in a transaction. 9 * Expected behaviour is that the checkpointed state is in the user 10 * context passed to the signal handler. The speculated state can be 11 * accessed with the uc_link pointer. 12 * 13 * The rationale for this is that if TM unaware code (which linked 14 * against TM libs) installs a signal handler it will not know of the 15 * speculative nature of the 'live' registers and may infer the wrong 16 * thing. 17 */ 18 19 #include <stdlib.h> 20 #include <stdio.h> 21 #include <string.h> 22 #include <signal.h> 23 #include <unistd.h> 24 25 #include <altivec.h> 26 27 #include "utils.h" 28 #include "tm.h" 29 30 #define MAX_ATTEMPT 500000 31 32 #define NV_VMX_REGS 12 33 34 long tm_signal_self_context_load(pid_t pid, long *gprs, double *fps, vector int *vms, vector int *vss); 35 36 static sig_atomic_t fail; 37 38 vector int vms[] = { 39 {1, 2, 3, 4 },{5, 6, 7, 8 },{9, 10,11,12}, 40 {13,14,15,16},{17,18,19,20},{21,22,23,24}, 41 {25,26,27,28},{29,30,31,32},{33,34,35,36}, 42 {37,38,39,40},{41,42,43,44},{45,46,47,48}, 43 {-1, -2, -3, -4}, {-5, -6, -7, -8}, {-9, -10,-11,-12}, 44 {-13,-14,-15,-16},{-17,-18,-19,-20},{-21,-22,-23,-24}, 45 {-25,-26,-27,-28},{-29,-30,-31,-32},{-33,-34,-35,-36}, 46 {-37,-38,-39,-40},{-41,-42,-43,-44},{-45,-46,-47,-48} 47 }; 48 49 static void signal_usr1(int signum, siginfo_t *info, void *uc) 50 { 51 int i; 52 ucontext_t *ucp = uc; 53 ucontext_t *tm_ucp = ucp->uc_link; 54 55 for (i = 0; i < NV_VMX_REGS && !fail; i++) { 56 fail = memcmp(ucp->uc_mcontext.v_regs->vrregs[i + 20], 57 &vms[i], sizeof(vector int)); 58 fail |= memcmp(tm_ucp->uc_mcontext.v_regs->vrregs[i + 20], 59 &vms[i + NV_VMX_REGS], sizeof (vector int)); 60 61 if (fail) { 62 int j; 63 64 fprintf(stderr, "Failed on %d vmx 0x", i); 65 for (j = 0; j < 4; j++) 66 fprintf(stderr, "%04x", ucp->uc_mcontext.v_regs->vrregs[i + 20][j]); 67 fprintf(stderr, " vs 0x"); 68 for (j = 0 ; j < 4; j++) 69 fprintf(stderr, "%04x", tm_ucp->uc_mcontext.v_regs->vrregs[i + 20][j]); 70 fprintf(stderr, "\n"); 71 } 72 } 73 } 74 75 static int tm_signal_context_chk() 76 { 77 struct sigaction act; 78 int i; 79 long rc; 80 pid_t pid = getpid(); 81 82 SKIP_IF(!have_htm()); 83 84 act.sa_sigaction = signal_usr1; 85 sigemptyset(&act.sa_mask); 86 act.sa_flags = SA_SIGINFO; 87 if (sigaction(SIGUSR1, &act, NULL) < 0) { 88 perror("sigaction sigusr1"); 89 exit(1); 90 } 91 92 i = 0; 93 while (i < MAX_ATTEMPT && !fail) { 94 rc = tm_signal_self_context_load(pid, NULL, NULL, vms, NULL); 95 FAIL_IF(rc != pid); 96 i++; 97 } 98 99 return fail; 100 } 101 102 int main(void) 103 { 104 return test_harness(tm_signal_context_chk, "tm_signal_context_chk_vmx"); 105 } 106