1f666ad41SAnshuman Khandual /*
2f666ad41SAnshuman Khandual  * Ptrace interface test helper functions
3f666ad41SAnshuman Khandual  *
4f666ad41SAnshuman Khandual  * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
5f666ad41SAnshuman Khandual  *
6f666ad41SAnshuman Khandual  * This program is free software; you can redistribute it and/or
7f666ad41SAnshuman Khandual  * modify it under the terms of the GNU General Public License
8f666ad41SAnshuman Khandual  * as published by the Free Software Foundation; either version
9f666ad41SAnshuman Khandual  * 2 of the License, or (at your option) any later version.
10f666ad41SAnshuman Khandual  */
11f666ad41SAnshuman Khandual #include <inttypes.h>
12f666ad41SAnshuman Khandual #include <unistd.h>
13f666ad41SAnshuman Khandual #include <stdlib.h>
14f666ad41SAnshuman Khandual #include <string.h>
15f666ad41SAnshuman Khandual #include <malloc.h>
16f666ad41SAnshuman Khandual #include <errno.h>
17f666ad41SAnshuman Khandual #include <time.h>
18f666ad41SAnshuman Khandual #include <sys/ptrace.h>
19f666ad41SAnshuman Khandual #include <sys/ioctl.h>
20f666ad41SAnshuman Khandual #include <sys/uio.h>
21f666ad41SAnshuman Khandual #include <sys/types.h>
22f666ad41SAnshuman Khandual #include <sys/wait.h>
23f666ad41SAnshuman Khandual #include <sys/signal.h>
24f666ad41SAnshuman Khandual #include <sys/ipc.h>
25f666ad41SAnshuman Khandual #include <sys/shm.h>
26f666ad41SAnshuman Khandual #include <sys/user.h>
27f666ad41SAnshuman Khandual #include <linux/elf.h>
28f666ad41SAnshuman Khandual #include <linux/types.h>
29f666ad41SAnshuman Khandual #include <linux/auxvec.h>
30f666ad41SAnshuman Khandual #include "reg.h"
31f666ad41SAnshuman Khandual #include "utils.h"
32f666ad41SAnshuman Khandual 
33f666ad41SAnshuman Khandual #define TEST_PASS 0
34f666ad41SAnshuman Khandual #define TEST_FAIL 1
35f666ad41SAnshuman Khandual 
36f666ad41SAnshuman Khandual struct fpr_regs {
37f666ad41SAnshuman Khandual 	unsigned long fpr[32];
38f666ad41SAnshuman Khandual 	unsigned long fpscr;
39f666ad41SAnshuman Khandual };
40f666ad41SAnshuman Khandual 
41f666ad41SAnshuman Khandual 
42f666ad41SAnshuman Khandual #ifndef NT_PPC_TAR
43f666ad41SAnshuman Khandual #define NT_PPC_TAR	0x103
44f666ad41SAnshuman Khandual #define NT_PPC_PPR	0x104
45f666ad41SAnshuman Khandual #define NT_PPC_DSCR	0x105
46f666ad41SAnshuman Khandual #define NT_PPC_EBB	0x106
47f666ad41SAnshuman Khandual #define NT_PPC_PMU	0x107
48f666ad41SAnshuman Khandual #define NT_PPC_TM_CGPR	0x108
49f666ad41SAnshuman Khandual #define NT_PPC_TM_CFPR	0x109
50f666ad41SAnshuman Khandual #define NT_PPC_TM_CVMX	0x10a
51f666ad41SAnshuman Khandual #define NT_PPC_TM_CVSX	0x10b
52f666ad41SAnshuman Khandual #define NT_PPC_TM_SPR	0x10c
53f666ad41SAnshuman Khandual #define NT_PPC_TM_CTAR	0x10d
54f666ad41SAnshuman Khandual #define NT_PPC_TM_CPPR	0x10e
55f666ad41SAnshuman Khandual #define NT_PPC_TM_CDSCR	0x10f
56f666ad41SAnshuman Khandual #endif
57f666ad41SAnshuman Khandual 
58f666ad41SAnshuman Khandual /* Basic ptrace operations */
59f666ad41SAnshuman Khandual int start_trace(pid_t child)
60f666ad41SAnshuman Khandual {
61f666ad41SAnshuman Khandual 	int ret;
62f666ad41SAnshuman Khandual 
63f666ad41SAnshuman Khandual 	ret = ptrace(PTRACE_ATTACH, child, NULL, NULL);
64f666ad41SAnshuman Khandual 	if (ret) {
65f666ad41SAnshuman Khandual 		perror("ptrace(PTRACE_ATTACH) failed");
66f666ad41SAnshuman Khandual 		return TEST_FAIL;
67f666ad41SAnshuman Khandual 	}
68f666ad41SAnshuman Khandual 	ret = waitpid(child, NULL, 0);
69f666ad41SAnshuman Khandual 	if (ret != child) {
70f666ad41SAnshuman Khandual 		perror("waitpid() failed");
71f666ad41SAnshuman Khandual 		return TEST_FAIL;
72f666ad41SAnshuman Khandual 	}
73f666ad41SAnshuman Khandual 	return TEST_PASS;
74f666ad41SAnshuman Khandual }
75f666ad41SAnshuman Khandual 
76f666ad41SAnshuman Khandual int stop_trace(pid_t child)
77f666ad41SAnshuman Khandual {
78f666ad41SAnshuman Khandual 	int ret;
79f666ad41SAnshuman Khandual 
80f666ad41SAnshuman Khandual 	ret = ptrace(PTRACE_DETACH, child, NULL, NULL);
81f666ad41SAnshuman Khandual 	if (ret) {
82f666ad41SAnshuman Khandual 		perror("ptrace(PTRACE_DETACH) failed");
83f666ad41SAnshuman Khandual 		return TEST_FAIL;
84f666ad41SAnshuman Khandual 	}
85f666ad41SAnshuman Khandual 	return TEST_PASS;
86f666ad41SAnshuman Khandual }
87f666ad41SAnshuman Khandual 
88f666ad41SAnshuman Khandual int cont_trace(pid_t child)
89f666ad41SAnshuman Khandual {
90f666ad41SAnshuman Khandual 	int ret;
91f666ad41SAnshuman Khandual 
92f666ad41SAnshuman Khandual 	ret = ptrace(PTRACE_CONT, child, NULL, NULL);
93f666ad41SAnshuman Khandual 	if (ret) {
94f666ad41SAnshuman Khandual 		perror("ptrace(PTRACE_CONT) failed");
95f666ad41SAnshuman Khandual 		return TEST_FAIL;
96f666ad41SAnshuman Khandual 	}
97f666ad41SAnshuman Khandual 	return TEST_PASS;
98f666ad41SAnshuman Khandual }
99f666ad41SAnshuman Khandual 
100254dae59SAnshuman Khandual /* TAR, PPR, DSCR */
101254dae59SAnshuman Khandual int show_tar_registers(pid_t child, unsigned long *out)
102254dae59SAnshuman Khandual {
103254dae59SAnshuman Khandual 	struct iovec iov;
104254dae59SAnshuman Khandual 	unsigned long *reg;
105254dae59SAnshuman Khandual 	int ret;
106254dae59SAnshuman Khandual 
107254dae59SAnshuman Khandual 	reg = malloc(sizeof(unsigned long));
108254dae59SAnshuman Khandual 	if (!reg) {
109254dae59SAnshuman Khandual 		perror("malloc() failed");
110254dae59SAnshuman Khandual 		return TEST_FAIL;
111254dae59SAnshuman Khandual 	}
112254dae59SAnshuman Khandual 	iov.iov_base = (u64 *) reg;
113254dae59SAnshuman Khandual 	iov.iov_len = sizeof(unsigned long);
114254dae59SAnshuman Khandual 
115254dae59SAnshuman Khandual 	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TAR, &iov);
116254dae59SAnshuman Khandual 	if (ret) {
117254dae59SAnshuman Khandual 		perror("ptrace(PTRACE_GETREGSET) failed");
118254dae59SAnshuman Khandual 		goto fail;
119254dae59SAnshuman Khandual 	}
120254dae59SAnshuman Khandual 	if (out)
121254dae59SAnshuman Khandual 		out[0] = *reg;
122254dae59SAnshuman Khandual 
123254dae59SAnshuman Khandual 	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_PPR, &iov);
124254dae59SAnshuman Khandual 	if (ret) {
125254dae59SAnshuman Khandual 		perror("ptrace(PTRACE_GETREGSET) failed");
126254dae59SAnshuman Khandual 		goto fail;
127254dae59SAnshuman Khandual 	}
128254dae59SAnshuman Khandual 	if (out)
129254dae59SAnshuman Khandual 		out[1] = *reg;
130254dae59SAnshuman Khandual 
131254dae59SAnshuman Khandual 	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_DSCR, &iov);
132254dae59SAnshuman Khandual 	if (ret) {
133254dae59SAnshuman Khandual 		perror("ptrace(PTRACE_GETREGSET) failed");
134254dae59SAnshuman Khandual 		goto fail;
135254dae59SAnshuman Khandual 	}
136254dae59SAnshuman Khandual 	if (out)
137254dae59SAnshuman Khandual 		out[2] = *reg;
138254dae59SAnshuman Khandual 
139254dae59SAnshuman Khandual 	free(reg);
140254dae59SAnshuman Khandual 	return TEST_PASS;
141254dae59SAnshuman Khandual fail:
142254dae59SAnshuman Khandual 	free(reg);
143254dae59SAnshuman Khandual 	return TEST_FAIL;
144254dae59SAnshuman Khandual }
145254dae59SAnshuman Khandual 
146254dae59SAnshuman Khandual int write_tar_registers(pid_t child, unsigned long tar,
147254dae59SAnshuman Khandual 		unsigned long ppr, unsigned long dscr)
148254dae59SAnshuman Khandual {
149254dae59SAnshuman Khandual 	struct iovec iov;
150254dae59SAnshuman Khandual 	unsigned long *reg;
151254dae59SAnshuman Khandual 	int ret;
152254dae59SAnshuman Khandual 
153254dae59SAnshuman Khandual 	reg = malloc(sizeof(unsigned long));
154254dae59SAnshuman Khandual 	if (!reg) {
155254dae59SAnshuman Khandual 		perror("malloc() failed");
156254dae59SAnshuman Khandual 		return TEST_FAIL;
157254dae59SAnshuman Khandual 	}
158254dae59SAnshuman Khandual 
159254dae59SAnshuman Khandual 	iov.iov_base = (u64 *) reg;
160254dae59SAnshuman Khandual 	iov.iov_len = sizeof(unsigned long);
161254dae59SAnshuman Khandual 
162254dae59SAnshuman Khandual 	*reg = tar;
163254dae59SAnshuman Khandual 	ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TAR, &iov);
164254dae59SAnshuman Khandual 	if (ret) {
165254dae59SAnshuman Khandual 		perror("ptrace(PTRACE_SETREGSET) failed");
166254dae59SAnshuman Khandual 		goto fail;
167254dae59SAnshuman Khandual 	}
168254dae59SAnshuman Khandual 
169254dae59SAnshuman Khandual 	*reg = ppr;
170254dae59SAnshuman Khandual 	ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_PPR, &iov);
171254dae59SAnshuman Khandual 	if (ret) {
172254dae59SAnshuman Khandual 		perror("ptrace(PTRACE_SETREGSET) failed");
173254dae59SAnshuman Khandual 		goto fail;
174254dae59SAnshuman Khandual 	}
175254dae59SAnshuman Khandual 
176254dae59SAnshuman Khandual 	*reg = dscr;
177254dae59SAnshuman Khandual 	ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_DSCR, &iov);
178254dae59SAnshuman Khandual 	if (ret) {
179254dae59SAnshuman Khandual 		perror("ptrace(PTRACE_SETREGSET) failed");
180254dae59SAnshuman Khandual 		goto fail;
181254dae59SAnshuman Khandual 	}
182254dae59SAnshuman Khandual 
183254dae59SAnshuman Khandual 	free(reg);
184254dae59SAnshuman Khandual 	return TEST_PASS;
185254dae59SAnshuman Khandual fail:
186254dae59SAnshuman Khandual 	free(reg);
187254dae59SAnshuman Khandual 	return TEST_FAIL;
188254dae59SAnshuman Khandual }
189254dae59SAnshuman Khandual 
190254dae59SAnshuman Khandual int show_tm_checkpointed_state(pid_t child, unsigned long *out)
191254dae59SAnshuman Khandual {
192254dae59SAnshuman Khandual 	struct iovec iov;
193254dae59SAnshuman Khandual 	unsigned long *reg;
194254dae59SAnshuman Khandual 	int ret;
195254dae59SAnshuman Khandual 
196254dae59SAnshuman Khandual 	reg = malloc(sizeof(unsigned long));
197254dae59SAnshuman Khandual 	if (!reg) {
198254dae59SAnshuman Khandual 		perror("malloc() failed");
199254dae59SAnshuman Khandual 		return TEST_FAIL;
200254dae59SAnshuman Khandual 	}
201254dae59SAnshuman Khandual 
202254dae59SAnshuman Khandual 	iov.iov_base = (u64 *) reg;
203254dae59SAnshuman Khandual 	iov.iov_len = sizeof(unsigned long);
204254dae59SAnshuman Khandual 
205254dae59SAnshuman Khandual 	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CTAR, &iov);
206254dae59SAnshuman Khandual 	if (ret) {
207254dae59SAnshuman Khandual 		perror("ptrace(PTRACE_GETREGSET) failed");
208254dae59SAnshuman Khandual 		goto fail;
209254dae59SAnshuman Khandual 	}
210254dae59SAnshuman Khandual 	if (out)
211254dae59SAnshuman Khandual 		out[0] = *reg;
212254dae59SAnshuman Khandual 
213254dae59SAnshuman Khandual 	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CPPR, &iov);
214254dae59SAnshuman Khandual 	if (ret) {
215254dae59SAnshuman Khandual 		perror("ptrace(PTRACE_GETREGSET) failed");
216254dae59SAnshuman Khandual 		goto fail;
217254dae59SAnshuman Khandual 	}
218254dae59SAnshuman Khandual 	if (out)
219254dae59SAnshuman Khandual 		out[1] = *reg;
220254dae59SAnshuman Khandual 
221254dae59SAnshuman Khandual 	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CDSCR, &iov);
222254dae59SAnshuman Khandual 	if (ret) {
223254dae59SAnshuman Khandual 		perror("ptrace(PTRACE_GETREGSET) failed");
224254dae59SAnshuman Khandual 		goto fail;
225254dae59SAnshuman Khandual 	}
226254dae59SAnshuman Khandual 	if (out)
227254dae59SAnshuman Khandual 		out[2] = *reg;
228254dae59SAnshuman Khandual 
229254dae59SAnshuman Khandual 	free(reg);
230254dae59SAnshuman Khandual 	return TEST_PASS;
231254dae59SAnshuman Khandual 
232254dae59SAnshuman Khandual fail:
233254dae59SAnshuman Khandual 	free(reg);
234254dae59SAnshuman Khandual 	return TEST_FAIL;
235254dae59SAnshuman Khandual }
236254dae59SAnshuman Khandual 
237254dae59SAnshuman Khandual int write_ckpt_tar_registers(pid_t child, unsigned long tar,
238254dae59SAnshuman Khandual 		unsigned long ppr, unsigned long dscr)
239254dae59SAnshuman Khandual {
240254dae59SAnshuman Khandual 	struct iovec iov;
241254dae59SAnshuman Khandual 	unsigned long *reg;
242254dae59SAnshuman Khandual 	int ret;
243254dae59SAnshuman Khandual 
244254dae59SAnshuman Khandual 	reg = malloc(sizeof(unsigned long));
245254dae59SAnshuman Khandual 	if (!reg) {
246254dae59SAnshuman Khandual 		perror("malloc() failed");
247254dae59SAnshuman Khandual 		return TEST_FAIL;
248254dae59SAnshuman Khandual 	}
249254dae59SAnshuman Khandual 
250254dae59SAnshuman Khandual 	iov.iov_base = (u64 *) reg;
251254dae59SAnshuman Khandual 	iov.iov_len = sizeof(unsigned long);
252254dae59SAnshuman Khandual 
253254dae59SAnshuman Khandual 	*reg = tar;
254254dae59SAnshuman Khandual 	ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CTAR, &iov);
255254dae59SAnshuman Khandual 	if (ret) {
256254dae59SAnshuman Khandual 		perror("ptrace(PTRACE_GETREGSET) failed");
257254dae59SAnshuman Khandual 		goto fail;
258254dae59SAnshuman Khandual 	}
259254dae59SAnshuman Khandual 
260254dae59SAnshuman Khandual 	*reg = ppr;
261254dae59SAnshuman Khandual 	ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CPPR, &iov);
262254dae59SAnshuman Khandual 	if (ret) {
263254dae59SAnshuman Khandual 		perror("ptrace(PTRACE_GETREGSET) failed");
264254dae59SAnshuman Khandual 		goto fail;
265254dae59SAnshuman Khandual 	}
266254dae59SAnshuman Khandual 
267254dae59SAnshuman Khandual 	*reg = dscr;
268254dae59SAnshuman Khandual 	ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CDSCR, &iov);
269254dae59SAnshuman Khandual 	if (ret) {
270254dae59SAnshuman Khandual 		perror("ptrace(PTRACE_GETREGSET) failed");
271254dae59SAnshuman Khandual 		goto fail;
272254dae59SAnshuman Khandual 	}
273254dae59SAnshuman Khandual 
274254dae59SAnshuman Khandual 	free(reg);
275254dae59SAnshuman Khandual 	return TEST_PASS;
276254dae59SAnshuman Khandual fail:
277254dae59SAnshuman Khandual 	free(reg);
278254dae59SAnshuman Khandual 	return TEST_FAIL;
279254dae59SAnshuman Khandual }
280254dae59SAnshuman Khandual 
281f666ad41SAnshuman Khandual /* FPR */
282f666ad41SAnshuman Khandual int show_fpr(pid_t child, unsigned long *fpr)
283f666ad41SAnshuman Khandual {
284f666ad41SAnshuman Khandual 	struct fpr_regs *regs;
285f666ad41SAnshuman Khandual 	int ret, i;
286f666ad41SAnshuman Khandual 
287f666ad41SAnshuman Khandual 	regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
288f666ad41SAnshuman Khandual 	ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs);
289f666ad41SAnshuman Khandual 	if (ret) {
290f666ad41SAnshuman Khandual 		perror("ptrace(PTRACE_GETREGSET) failed");
291f666ad41SAnshuman Khandual 		return TEST_FAIL;
292f666ad41SAnshuman Khandual 	}
293f666ad41SAnshuman Khandual 
294f666ad41SAnshuman Khandual 	if (fpr) {
295f666ad41SAnshuman Khandual 		for (i = 0; i < 32; i++)
296f666ad41SAnshuman Khandual 			fpr[i] = regs->fpr[i];
297f666ad41SAnshuman Khandual 	}
298f666ad41SAnshuman Khandual 	return TEST_PASS;
299f666ad41SAnshuman Khandual }
300f666ad41SAnshuman Khandual 
301f666ad41SAnshuman Khandual int write_fpr(pid_t child, unsigned long val)
302f666ad41SAnshuman Khandual {
303f666ad41SAnshuman Khandual 	struct fpr_regs *regs;
304f666ad41SAnshuman Khandual 	int ret, i;
305f666ad41SAnshuman Khandual 
306f666ad41SAnshuman Khandual 	regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
307f666ad41SAnshuman Khandual 	ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs);
308f666ad41SAnshuman Khandual 	if (ret) {
309f666ad41SAnshuman Khandual 		perror("ptrace(PTRACE_GETREGSET) failed");
310f666ad41SAnshuman Khandual 		return TEST_FAIL;
311f666ad41SAnshuman Khandual 	}
312f666ad41SAnshuman Khandual 
313f666ad41SAnshuman Khandual 	for (i = 0; i < 32; i++)
314f666ad41SAnshuman Khandual 		regs->fpr[i] = val;
315f666ad41SAnshuman Khandual 
316f666ad41SAnshuman Khandual 	ret = ptrace(PTRACE_SETFPREGS, child, NULL, regs);
317f666ad41SAnshuman Khandual 	if (ret) {
318f666ad41SAnshuman Khandual 		perror("ptrace(PTRACE_GETREGSET) failed");
319f666ad41SAnshuman Khandual 		return TEST_FAIL;
320f666ad41SAnshuman Khandual 	}
321f666ad41SAnshuman Khandual 	return TEST_PASS;
322f666ad41SAnshuman Khandual }
323f666ad41SAnshuman Khandual 
324f666ad41SAnshuman Khandual int show_ckpt_fpr(pid_t child, unsigned long *fpr)
325f666ad41SAnshuman Khandual {
326f666ad41SAnshuman Khandual 	struct fpr_regs *regs;
327f666ad41SAnshuman Khandual 	struct iovec iov;
328f666ad41SAnshuman Khandual 	int ret, i;
329f666ad41SAnshuman Khandual 
330f666ad41SAnshuman Khandual 	regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
331f666ad41SAnshuman Khandual 	iov.iov_base = regs;
332f666ad41SAnshuman Khandual 	iov.iov_len = sizeof(struct fpr_regs);
333f666ad41SAnshuman Khandual 
334f666ad41SAnshuman Khandual 	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov);
335f666ad41SAnshuman Khandual 	if (ret) {
336f666ad41SAnshuman Khandual 		perror("ptrace(PTRACE_GETREGSET) failed");
337f666ad41SAnshuman Khandual 		return TEST_FAIL;
338f666ad41SAnshuman Khandual 	}
339f666ad41SAnshuman Khandual 
340f666ad41SAnshuman Khandual 	if (fpr) {
341f666ad41SAnshuman Khandual 		for (i = 0; i < 32; i++)
342f666ad41SAnshuman Khandual 			fpr[i] = regs->fpr[i];
343f666ad41SAnshuman Khandual 	}
344f666ad41SAnshuman Khandual 
345f666ad41SAnshuman Khandual 	return TEST_PASS;
346f666ad41SAnshuman Khandual }
347f666ad41SAnshuman Khandual 
348f666ad41SAnshuman Khandual int write_ckpt_fpr(pid_t child, unsigned long val)
349f666ad41SAnshuman Khandual {
350f666ad41SAnshuman Khandual 	struct fpr_regs *regs;
351f666ad41SAnshuman Khandual 	struct iovec iov;
352f666ad41SAnshuman Khandual 	int ret, i;
353f666ad41SAnshuman Khandual 
354f666ad41SAnshuman Khandual 	regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
355f666ad41SAnshuman Khandual 	iov.iov_base = regs;
356f666ad41SAnshuman Khandual 	iov.iov_len = sizeof(struct fpr_regs);
357f666ad41SAnshuman Khandual 
358f666ad41SAnshuman Khandual 	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov);
359f666ad41SAnshuman Khandual 	if (ret) {
360f666ad41SAnshuman Khandual 		perror("ptrace(PTRACE_GETREGSET) failed");
361f666ad41SAnshuman Khandual 		return TEST_FAIL;
362f666ad41SAnshuman Khandual 	}
363f666ad41SAnshuman Khandual 
364f666ad41SAnshuman Khandual 	for (i = 0; i < 32; i++)
365f666ad41SAnshuman Khandual 		regs->fpr[i] = val;
366f666ad41SAnshuman Khandual 
367f666ad41SAnshuman Khandual 	ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CFPR, &iov);
368f666ad41SAnshuman Khandual 	if (ret) {
369f666ad41SAnshuman Khandual 		perror("ptrace(PTRACE_GETREGSET) failed");
370f666ad41SAnshuman Khandual 		return TEST_FAIL;
371f666ad41SAnshuman Khandual 	}
372f666ad41SAnshuman Khandual 	return TEST_PASS;
373f666ad41SAnshuman Khandual }
374f666ad41SAnshuman Khandual 
375f666ad41SAnshuman Khandual /* GPR */
376f666ad41SAnshuman Khandual int show_gpr(pid_t child, unsigned long *gpr)
377f666ad41SAnshuman Khandual {
378f666ad41SAnshuman Khandual 	struct pt_regs *regs;
379f666ad41SAnshuman Khandual 	int ret, i;
380f666ad41SAnshuman Khandual 
381f666ad41SAnshuman Khandual 	regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
382f666ad41SAnshuman Khandual 	if (!regs) {
383f666ad41SAnshuman Khandual 		perror("malloc() failed");
384f666ad41SAnshuman Khandual 		return TEST_FAIL;
385f666ad41SAnshuman Khandual 	}
386f666ad41SAnshuman Khandual 
387f666ad41SAnshuman Khandual 	ret = ptrace(PTRACE_GETREGS, child, NULL, regs);
388f666ad41SAnshuman Khandual 	if (ret) {
389f666ad41SAnshuman Khandual 		perror("ptrace(PTRACE_GETREGSET) failed");
390f666ad41SAnshuman Khandual 		return TEST_FAIL;
391f666ad41SAnshuman Khandual 	}
392f666ad41SAnshuman Khandual 
393f666ad41SAnshuman Khandual 	if (gpr) {
394f666ad41SAnshuman Khandual 		for (i = 14; i < 32; i++)
395f666ad41SAnshuman Khandual 			gpr[i-14] = regs->gpr[i];
396f666ad41SAnshuman Khandual 	}
397f666ad41SAnshuman Khandual 
398f666ad41SAnshuman Khandual 	return TEST_PASS;
399f666ad41SAnshuman Khandual }
400f666ad41SAnshuman Khandual 
401f666ad41SAnshuman Khandual int write_gpr(pid_t child, unsigned long val)
402f666ad41SAnshuman Khandual {
403f666ad41SAnshuman Khandual 	struct pt_regs *regs;
404f666ad41SAnshuman Khandual 	int i, ret;
405f666ad41SAnshuman Khandual 
406f666ad41SAnshuman Khandual 	regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
407f666ad41SAnshuman Khandual 	if (!regs) {
408f666ad41SAnshuman Khandual 		perror("malloc() failed");
409f666ad41SAnshuman Khandual 		return TEST_FAIL;
410f666ad41SAnshuman Khandual 	}
411f666ad41SAnshuman Khandual 
412f666ad41SAnshuman Khandual 	ret = ptrace(PTRACE_GETREGS, child, NULL, regs);
413f666ad41SAnshuman Khandual 	if (ret) {
414f666ad41SAnshuman Khandual 		perror("ptrace(PTRACE_GETREGSET) failed");
415f666ad41SAnshuman Khandual 		return TEST_FAIL;
416f666ad41SAnshuman Khandual 	}
417f666ad41SAnshuman Khandual 
418f666ad41SAnshuman Khandual 	for (i = 14; i < 32; i++)
419f666ad41SAnshuman Khandual 		regs->gpr[i] = val;
420f666ad41SAnshuman Khandual 
421f666ad41SAnshuman Khandual 	ret = ptrace(PTRACE_SETREGS, child, NULL, regs);
422f666ad41SAnshuman Khandual 	if (ret) {
423f666ad41SAnshuman Khandual 		perror("ptrace(PTRACE_GETREGSET) failed");
424f666ad41SAnshuman Khandual 		return TEST_FAIL;
425f666ad41SAnshuman Khandual 	}
426f666ad41SAnshuman Khandual 	return TEST_PASS;
427f666ad41SAnshuman Khandual }
428f666ad41SAnshuman Khandual 
429f666ad41SAnshuman Khandual int show_ckpt_gpr(pid_t child, unsigned long *gpr)
430f666ad41SAnshuman Khandual {
431f666ad41SAnshuman Khandual 	struct pt_regs *regs;
432f666ad41SAnshuman Khandual 	struct iovec iov;
433f666ad41SAnshuman Khandual 	int ret, i;
434f666ad41SAnshuman Khandual 
435f666ad41SAnshuman Khandual 	regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
436f666ad41SAnshuman Khandual 	if (!regs) {
437f666ad41SAnshuman Khandual 		perror("malloc() failed");
438f666ad41SAnshuman Khandual 		return TEST_FAIL;
439f666ad41SAnshuman Khandual 	}
440f666ad41SAnshuman Khandual 
441f666ad41SAnshuman Khandual 	iov.iov_base = (u64 *) regs;
442f666ad41SAnshuman Khandual 	iov.iov_len = sizeof(struct pt_regs);
443f666ad41SAnshuman Khandual 
444f666ad41SAnshuman Khandual 	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov);
445f666ad41SAnshuman Khandual 	if (ret) {
446f666ad41SAnshuman Khandual 		perror("ptrace(PTRACE_GETREGSET) failed");
447f666ad41SAnshuman Khandual 		return TEST_FAIL;
448f666ad41SAnshuman Khandual 	}
449f666ad41SAnshuman Khandual 
450f666ad41SAnshuman Khandual 	if (gpr) {
451f666ad41SAnshuman Khandual 		for (i = 14; i < 32; i++)
452f666ad41SAnshuman Khandual 			gpr[i-14] = regs->gpr[i];
453f666ad41SAnshuman Khandual 	}
454f666ad41SAnshuman Khandual 
455f666ad41SAnshuman Khandual 	return TEST_PASS;
456f666ad41SAnshuman Khandual }
457f666ad41SAnshuman Khandual 
458f666ad41SAnshuman Khandual int write_ckpt_gpr(pid_t child, unsigned long val)
459f666ad41SAnshuman Khandual {
460f666ad41SAnshuman Khandual 	struct pt_regs *regs;
461f666ad41SAnshuman Khandual 	struct iovec iov;
462f666ad41SAnshuman Khandual 	int ret, i;
463f666ad41SAnshuman Khandual 
464f666ad41SAnshuman Khandual 	regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
465f666ad41SAnshuman Khandual 	if (!regs) {
466f666ad41SAnshuman Khandual 		perror("malloc() failed\n");
467f666ad41SAnshuman Khandual 		return TEST_FAIL;
468f666ad41SAnshuman Khandual 	}
469f666ad41SAnshuman Khandual 	iov.iov_base = (u64 *) regs;
470f666ad41SAnshuman Khandual 	iov.iov_len = sizeof(struct pt_regs);
471f666ad41SAnshuman Khandual 
472f666ad41SAnshuman Khandual 	ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov);
473f666ad41SAnshuman Khandual 	if (ret) {
474f666ad41SAnshuman Khandual 		perror("ptrace(PTRACE_GETREGSET) failed");
475f666ad41SAnshuman Khandual 		return TEST_FAIL;
476f666ad41SAnshuman Khandual 	}
477f666ad41SAnshuman Khandual 
478f666ad41SAnshuman Khandual 	for (i = 14; i < 32; i++)
479f666ad41SAnshuman Khandual 		regs->gpr[i] = val;
480f666ad41SAnshuman Khandual 
481f666ad41SAnshuman Khandual 	ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CGPR, &iov);
482f666ad41SAnshuman Khandual 	if (ret) {
483f666ad41SAnshuman Khandual 		perror("ptrace(PTRACE_GETREGSET) failed");
484f666ad41SAnshuman Khandual 		return TEST_FAIL;
485f666ad41SAnshuman Khandual 	}
486f666ad41SAnshuman Khandual 	return TEST_PASS;
487f666ad41SAnshuman Khandual }
488f666ad41SAnshuman Khandual 
489f666ad41SAnshuman Khandual /* Analyse TEXASR after TM failure */
490f666ad41SAnshuman Khandual inline unsigned long get_tfiar(void)
491f666ad41SAnshuman Khandual {
492f666ad41SAnshuman Khandual 	unsigned long ret;
493f666ad41SAnshuman Khandual 
494f666ad41SAnshuman Khandual 	asm volatile("mfspr %0,%1" : "=r" (ret) : "i" (SPRN_TFIAR));
495f666ad41SAnshuman Khandual 	return ret;
496f666ad41SAnshuman Khandual }
497f666ad41SAnshuman Khandual 
498f666ad41SAnshuman Khandual void analyse_texasr(unsigned long texasr)
499f666ad41SAnshuman Khandual {
500f666ad41SAnshuman Khandual 	printf("TEXASR: %16lx\t", texasr);
501f666ad41SAnshuman Khandual 
502f666ad41SAnshuman Khandual 	if (texasr & TEXASR_FP)
503f666ad41SAnshuman Khandual 		printf("TEXASR_FP  ");
504f666ad41SAnshuman Khandual 
505f666ad41SAnshuman Khandual 	if (texasr & TEXASR_DA)
506f666ad41SAnshuman Khandual 		printf("TEXASR_DA  ");
507f666ad41SAnshuman Khandual 
508f666ad41SAnshuman Khandual 	if (texasr & TEXASR_NO)
509f666ad41SAnshuman Khandual 		printf("TEXASR_NO  ");
510f666ad41SAnshuman Khandual 
511f666ad41SAnshuman Khandual 	if (texasr & TEXASR_FO)
512f666ad41SAnshuman Khandual 		printf("TEXASR_FO  ");
513f666ad41SAnshuman Khandual 
514f666ad41SAnshuman Khandual 	if (texasr & TEXASR_SIC)
515f666ad41SAnshuman Khandual 		printf("TEXASR_SIC  ");
516f666ad41SAnshuman Khandual 
517f666ad41SAnshuman Khandual 	if (texasr & TEXASR_NTC)
518f666ad41SAnshuman Khandual 		printf("TEXASR_NTC  ");
519f666ad41SAnshuman Khandual 
520f666ad41SAnshuman Khandual 	if (texasr & TEXASR_TC)
521f666ad41SAnshuman Khandual 		printf("TEXASR_TC  ");
522f666ad41SAnshuman Khandual 
523f666ad41SAnshuman Khandual 	if (texasr & TEXASR_TIC)
524f666ad41SAnshuman Khandual 		printf("TEXASR_TIC  ");
525f666ad41SAnshuman Khandual 
526f666ad41SAnshuman Khandual 	if (texasr & TEXASR_IC)
527f666ad41SAnshuman Khandual 		printf("TEXASR_IC  ");
528f666ad41SAnshuman Khandual 
529f666ad41SAnshuman Khandual 	if (texasr & TEXASR_IFC)
530f666ad41SAnshuman Khandual 		printf("TEXASR_IFC  ");
531f666ad41SAnshuman Khandual 
532f666ad41SAnshuman Khandual 	if (texasr & TEXASR_ABT)
533f666ad41SAnshuman Khandual 		printf("TEXASR_ABT  ");
534f666ad41SAnshuman Khandual 
535f666ad41SAnshuman Khandual 	if (texasr & TEXASR_SPD)
536f666ad41SAnshuman Khandual 		printf("TEXASR_SPD  ");
537f666ad41SAnshuman Khandual 
538f666ad41SAnshuman Khandual 	if (texasr & TEXASR_HV)
539f666ad41SAnshuman Khandual 		printf("TEXASR_HV  ");
540f666ad41SAnshuman Khandual 
541f666ad41SAnshuman Khandual 	if (texasr & TEXASR_PR)
542f666ad41SAnshuman Khandual 		printf("TEXASR_PR  ");
543f666ad41SAnshuman Khandual 
544f666ad41SAnshuman Khandual 	if (texasr & TEXASR_FS)
545f666ad41SAnshuman Khandual 		printf("TEXASR_FS  ");
546f666ad41SAnshuman Khandual 
547f666ad41SAnshuman Khandual 	if (texasr & TEXASR_TE)
548f666ad41SAnshuman Khandual 		printf("TEXASR_TE  ");
549f666ad41SAnshuman Khandual 
550f666ad41SAnshuman Khandual 	if (texasr & TEXASR_ROT)
551f666ad41SAnshuman Khandual 		printf("TEXASR_ROT  ");
552f666ad41SAnshuman Khandual 
553f666ad41SAnshuman Khandual 	printf("TFIAR :%lx\n", get_tfiar());
554f666ad41SAnshuman Khandual }
555f666ad41SAnshuman Khandual 
556f666ad41SAnshuman Khandual void store_gpr(unsigned long *addr);
557f666ad41SAnshuman Khandual void store_fpr(float *addr);
558