hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/tools/testing/selftests/powerpc/tm/tm-signal-context-chk-fpu.c
....@@ -1,19 +1,15 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Copyright 2016, Cyril Bur, IBM Corp.
3
- *
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.
8
- *
94 *
105 * Test the kernel's signal frame code.
116 *
127 * The kernel sets up two sets of ucontexts if the signal was to be
13
- * delivered while the thread was in a transaction.
8
+ * delivered while the thread was in a transaction (referred too as
9
+ * first and second contexts).
1410 * 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.
11
+ * context passed to the signal handler (first context). The speculated
12
+ * state can be accessed with the uc_link pointer (second context).
1713 *
1814 * The rationale for this is that if TM unaware code (which linked
1915 * against TM libs) installs a signal handler it will not know of the
....@@ -33,17 +29,20 @@
3329
3430 #define MAX_ATTEMPT 500000
3531
36
-#define NV_FPU_REGS 18
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 */
3734
3835 long tm_signal_self_context_load(pid_t pid, long *gprs, double *fps, vector int *vms, vector int *vss);
3936
40
-/* Be sure there are 2x as many as there are NV FPU regs (2x18) */
37
+/* Test only non-volatile registers, i.e. 18 fpr registers from f14 to f31 */
4138 static double fps[] = {
39
+ /* First context will be set with these values, i.e. non-speculative */
4240 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 */
4342 -1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18
4443 };
4544
46
-static sig_atomic_t fail;
45
+static sig_atomic_t fail, broken;
4746
4847 static void signal_usr1(int signum, siginfo_t *info, void *uc)
4948 {
....@@ -51,11 +50,24 @@
5150 ucontext_t *ucp = uc;
5251 ucontext_t *tm_ucp = ucp->uc_link;
5352
54
- for (i = 0; i < NV_FPU_REGS && !fail; i++) {
55
- fail = (ucp->uc_mcontext.fp_regs[i + 14] != fps[i]);
56
- fail |= (tm_ucp->uc_mcontext.fp_regs[i + 14] != fps[i + NV_FPU_REGS]);
57
- if (fail)
58
- printf("Failed on %d FP %g or %g\n", i, ucp->uc_mcontext.fp_regs[i + 14], tm_ucp->uc_mcontext.fp_regs[i + 14]);
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]);
56
+ if (fail) {
57
+ broken = 1;
58
+ printf("FPR%d (1st context) == %g instead of %g (expected)\n",
59
+ FPR14 + i, ucp->uc_mcontext.fp_regs[FPR14 + i], fps[i]);
60
+ }
61
+ }
62
+
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]);
66
+ if (fail) {
67
+ broken = 1;
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]);
70
+ }
5971 }
6072 }
6173
....@@ -77,13 +89,19 @@
7789 }
7890
7991 i = 0;
80
- while (i < MAX_ATTEMPT && !fail) {
92
+ while (i < MAX_ATTEMPT && !broken) {
93
+ /*
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.
98
+ */
8199 rc = tm_signal_self_context_load(pid, NULL, fps, NULL, NULL);
82100 FAIL_IF(rc != pid);
83101 i++;
84102 }
85103
86
- return fail;
104
+ return (broken);
87105 }
88106
89107 int main(void)