1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Ptrace test for GPR/FPR registers in TM context |
4 | * |
5 | * Copyright (C) 2015 Anshuman Khandual, IBM Corporation. |
6 | */ |
7 | #include "ptrace.h" |
8 | #include "ptrace-gpr.h" |
9 | #include "tm.h" |
10 | |
11 | /* Tracer and Tracee Shared Data */ |
12 | int shm_id; |
13 | unsigned long *cptr, *pptr; |
14 | |
15 | double a = FPR_1; |
16 | double b = FPR_2; |
17 | double c = FPR_3; |
18 | |
19 | void tm_gpr(void) |
20 | { |
21 | unsigned long gpr_buf[18]; |
22 | unsigned long result, texasr; |
23 | double fpr_buf[32]; |
24 | |
25 | printf("Starting the child\n" ); |
26 | cptr = (unsigned long *)shmat(shm_id, NULL, 0); |
27 | |
28 | trans: |
29 | cptr[1] = 0; |
30 | asm __volatile__( |
31 | ASM_LOAD_GPR_IMMED(gpr_1) |
32 | ASM_LOAD_FPR(flt_1) |
33 | "1: ;" |
34 | "tbegin.;" |
35 | "beq 2f;" |
36 | ASM_LOAD_GPR_IMMED(gpr_2) |
37 | ASM_LOAD_FPR(flt_2) |
38 | "tsuspend.;" |
39 | "li 7, 1;" |
40 | "stw 7, 0(%[cptr1]);" |
41 | "tresume.;" |
42 | "b .;" |
43 | |
44 | "tend.;" |
45 | "li 0, 0;" |
46 | "ori %[res], 0, 0;" |
47 | "b 3f;" |
48 | |
49 | /* Transaction abort handler */ |
50 | "2: ;" |
51 | "li 0, 1;" |
52 | "ori %[res], 0, 0;" |
53 | "mfspr %[texasr], %[sprn_texasr];" |
54 | |
55 | "3: ;" |
56 | : [res] "=r" (result), [texasr] "=r" (texasr) |
57 | : [gpr_1]"i" (GPR_1), [gpr_2]"i" (GPR_2), |
58 | [sprn_texasr] "i" (SPRN_TEXASR), [flt_1] "b" (&a), |
59 | [flt_2] "b" (&b), [cptr1] "b" (&cptr[1]) |
60 | : "memory" , "r0" , "r7" , "r8" , "r9" , "r10" , |
61 | "r11" , "r12" , "r13" , "r14" , "r15" , "r16" , |
62 | "r17" , "r18" , "r19" , "r20" , "r21" , "r22" , |
63 | "r23" , "r24" , "r25" , "r26" , "r27" , "r28" , |
64 | "r29" , "r30" , "r31" |
65 | ); |
66 | |
67 | if (result) { |
68 | if (!cptr[0]) |
69 | goto trans; |
70 | |
71 | shmdt((void *)cptr); |
72 | store_gpr(addr: gpr_buf); |
73 | store_fpr(fpr_buf); |
74 | |
75 | if (validate_gpr(gpr: gpr_buf, GPR_3)) |
76 | exit(1); |
77 | |
78 | if (validate_fpr_double(fpr: fpr_buf, val: c)) |
79 | exit(1); |
80 | |
81 | exit(0); |
82 | } |
83 | shmdt((void *)cptr); |
84 | exit(1); |
85 | } |
86 | |
87 | int trace_tm_gpr(pid_t child) |
88 | { |
89 | unsigned long gpr[18]; |
90 | __u64 fpr[32]; |
91 | |
92 | FAIL_IF(start_trace(child)); |
93 | FAIL_IF(show_gpr(child, gpr)); |
94 | FAIL_IF(validate_gpr(gpr, GPR_2)); |
95 | FAIL_IF(show_fpr(child, fpr)); |
96 | FAIL_IF(validate_fpr(fpr, FPR_2_REP)); |
97 | FAIL_IF(show_ckpt_fpr(child, fpr)); |
98 | FAIL_IF(validate_fpr(fpr, FPR_1_REP)); |
99 | FAIL_IF(show_ckpt_gpr(child, gpr)); |
100 | FAIL_IF(validate_gpr(gpr, GPR_1)); |
101 | FAIL_IF(write_ckpt_gpr(child, GPR_3)); |
102 | FAIL_IF(write_ckpt_fpr(child, FPR_3_REP)); |
103 | |
104 | pptr[0] = 1; |
105 | FAIL_IF(stop_trace(child)); |
106 | |
107 | return TEST_PASS; |
108 | } |
109 | |
110 | int ptrace_tm_gpr(void) |
111 | { |
112 | pid_t pid; |
113 | int ret, status; |
114 | |
115 | SKIP_IF_MSG(!have_htm(), "Don't have transactional memory" ); |
116 | SKIP_IF_MSG(htm_is_synthetic(), "Transactional memory is synthetic" ); |
117 | shm_id = shmget(IPC_PRIVATE, sizeof(int) * 2, 0777|IPC_CREAT); |
118 | pid = fork(); |
119 | if (pid < 0) { |
120 | perror("fork() failed" ); |
121 | return TEST_FAIL; |
122 | } |
123 | if (pid == 0) |
124 | tm_gpr(); |
125 | |
126 | if (pid) { |
127 | pptr = (unsigned long *)shmat(shm_id, NULL, 0); |
128 | |
129 | while (!pptr[1]) |
130 | asm volatile("" : : : "memory" ); |
131 | ret = trace_tm_gpr(child: pid); |
132 | if (ret) { |
133 | kill(pid, SIGTERM); |
134 | return TEST_FAIL; |
135 | } |
136 | |
137 | shmdt((void *)pptr); |
138 | |
139 | ret = wait(&status); |
140 | shmctl(shm_id, IPC_RMID, NULL); |
141 | if (ret != pid) { |
142 | printf("Child's exit status not captured\n" ); |
143 | return TEST_FAIL; |
144 | } |
145 | |
146 | return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL : |
147 | TEST_PASS; |
148 | } |
149 | return TEST_PASS; |
150 | } |
151 | |
152 | int main(int argc, char *argv[]) |
153 | { |
154 | return test_harness(ptrace_tm_gpr, "ptrace_tm_gpr" ); |
155 | } |
156 | |