2 * Copyright 2016, Cyril Bur, IBM Corp.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
10 * Test the kernel's signal frame code.
12 * The kernel sets up two sets of ucontexts if the signal was to be
13 * delivered while the thread was in a transaction.
14 * Expected behaviour is that the checkpointed state is in the user
15 * context passed to the signal handler. The speculated state can be
16 * accessed with the uc_link pointer.
18 * The rationale for this is that if TM unaware code (which linked
19 * against TM libs) installs a signal handler it will not know of the
20 * speculative nature of the 'live' registers and may infer the wrong
35 #define MAX_ATTEMPT 500000
37 #define NV_VSX_REGS 12
39 long tm_signal_self_context_load(pid_t pid
, long *gprs
, double *fps
, vector
int *vms
, vector
int *vss
);
41 static sig_atomic_t fail
;
44 {1, 2, 3, 4 },{5, 6, 7, 8 },{9, 10,11,12},
45 {13,14,15,16},{17,18,19,20},{21,22,23,24},
46 {25,26,27,28},{29,30,31,32},{33,34,35,36},
47 {37,38,39,40},{41,42,43,44},{45,46,47,48},
48 {-1, -2, -3, -4 },{-5, -6, -7, -8 },{-9, -10,-11,-12},
49 {-13,-14,-15,-16},{-17,-18,-19,-20},{-21,-22,-23,-24},
50 {-25,-26,-27,-28},{-29,-30,-31,-32},{-33,-34,-35,-36},
51 {-37,-38,-39,-40},{-41,-42,-43,-44},{-45,-46,-47,-48}
54 static void signal_usr1(int signum
, siginfo_t
*info
, void *uc
)
57 uint8_t vsc
[sizeof(vector
int)];
58 uint8_t vst
[sizeof(vector
int)];
60 ucontext_t
*tm_ucp
= ucp
->uc_link
;
63 * The other half of the VSX regs will be after v_regs.
65 * In short, vmx_reserve array holds everything. v_regs is a 16
66 * byte aligned pointer at the start of vmx_reserve (vmx_reserve
67 * may or may not be 16 aligned) where the v_regs structure exists.
68 * (half of) The VSX regsters are directly after v_regs so the
69 * easiest way to find them below.
71 long *vsx_ptr
= (long *)(ucp
->uc_mcontext
.v_regs
+ 1);
72 long *tm_vsx_ptr
= (long *)(tm_ucp
->uc_mcontext
.v_regs
+ 1);
73 for (i
= 0; i
< NV_VSX_REGS
&& !fail
; i
++) {
74 memcpy(vsc
, &ucp
->uc_mcontext
.fp_regs
[i
+ 20], 8);
75 memcpy(vsc
+ 8, &vsx_ptr
[20 + i
], 8);
76 fail
= memcmp(vsc
, &vss
[i
], sizeof(vector
int));
77 memcpy(vst
, &tm_ucp
->uc_mcontext
.fp_regs
[i
+ 20], 8);
78 memcpy(vst
+ 8, &tm_vsx_ptr
[20 + i
], 8);
79 fail
|= memcmp(vst
, &vss
[i
+ NV_VSX_REGS
], sizeof(vector
int));
84 fprintf(stderr
, "Failed on %d vsx 0x", i
);
85 for (j
= 0; j
< 16; j
++)
86 fprintf(stderr
, "%02x", vsc
[j
]);
87 fprintf(stderr
, " vs 0x");
88 for (j
= 0; j
< 16; j
++)
89 fprintf(stderr
, "%02x", vst
[j
]);
90 fprintf(stderr
, "\n");
95 static int tm_signal_context_chk()
100 pid_t pid
= getpid();
102 SKIP_IF(!have_htm());
104 act
.sa_sigaction
= signal_usr1
;
105 sigemptyset(&act
.sa_mask
);
106 act
.sa_flags
= SA_SIGINFO
;
107 if (sigaction(SIGUSR1
, &act
, NULL
) < 0) {
108 perror("sigaction sigusr1");
113 while (i
< MAX_ATTEMPT
&& !fail
) {
114 rc
= tm_signal_self_context_load(pid
, NULL
, NULL
, NULL
, vss
);
124 return test_harness(tm_signal_context_chk
, "tm_signal_context_chk_vsx");