1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright 2016, Cyril Bur, IBM Corp.
5 * Test the kernel's signal frame code.
7 * The kernel sets up two sets of ucontexts if the signal was to be
8 * delivered while the thread was in a transaction (referred too as
9 * first and second contexts).
10 * Expected behaviour is that the checkpointed state is in the user
11 * context passed to the signal handler (first context). The speculated
12 * state can be accessed with the uc_link pointer (second context).
14 * The rationale for this is that if TM unaware code (which linked
15 * against TM libs) installs a signal handler it will not know of the
16 * speculative nature of the 'live' registers and may infer the wrong
30 #define MAX_ATTEMPT 500000
32 #define NV_FPU_REGS 18 /* Number of non-volatile FP registers */
33 #define FPR14 14 /* First non-volatile FP register to check in f14-31 subset */
35 long tm_signal_self_context_load(pid_t pid
, long *gprs
, double *fps
, vector
int *vms
, vector
int *vss
);
37 /* Test only non-volatile registers, i.e. 18 fpr registers from f14 to f31 */
38 static double fps
[] = {
39 /* First context will be set with these values, i.e. non-speculative */
40 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
41 /* Second context will be set with these values, i.e. speculative */
42 -1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18
45 static sig_atomic_t fail
, broken
;
47 static void signal_usr1(int signum
, siginfo_t
*info
, void *uc
)
51 ucontext_t
*tm_ucp
= ucp
->uc_link
;
53 for (i
= 0; i
< NV_FPU_REGS
; i
++) {
54 /* Check first context. Print all mismatches. */
55 fail
= (ucp
->uc_mcontext
.fp_regs
[FPR14
+ i
] != fps
[i
]);
58 printf("FPR%d (1st context) == %g instead of %g (expected)\n",
59 FPR14
+ i
, ucp
->uc_mcontext
.fp_regs
[FPR14
+ i
], fps
[i
]);
63 for (i
= 0; i
< NV_FPU_REGS
; i
++) {
64 /* Check second context. Print all mismatches. */
65 fail
= (tm_ucp
->uc_mcontext
.fp_regs
[FPR14
+ i
] != fps
[NV_FPU_REGS
+ i
]);
68 printf("FPR%d (2nd context) == %g instead of %g (expected)\n",
69 FPR14
+ i
, tm_ucp
->uc_mcontext
.fp_regs
[FPR14
+ i
], fps
[NV_FPU_REGS
+ i
]);
74 static int tm_signal_context_chk_fpu()
83 act
.sa_sigaction
= signal_usr1
;
84 sigemptyset(&act
.sa_mask
);
85 act
.sa_flags
= SA_SIGINFO
;
86 if (sigaction(SIGUSR1
, &act
, NULL
) < 0) {
87 perror("sigaction sigusr1");
92 while (i
< MAX_ATTEMPT
&& !broken
) {
94 * tm_signal_self_context_load will set both first and second
95 * contexts accordingly to the values passed through non-NULL
96 * array pointers to it, in that case 'fps', and invoke the
97 * signal handler installed for SIGUSR1.
99 rc
= tm_signal_self_context_load(pid
, NULL
, fps
, NULL
, NULL
);
109 return test_harness(tm_signal_context_chk_fpu
, "tm_signal_context_chk_fpu");