1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3 * Ptrace interface test helper functions
4 *
5 * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
6 */
7
8 #define __SANE_USERSPACE_TYPES__
9
10 #include <inttypes.h>
11 #include <unistd.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <malloc.h>
15 #include <errno.h>
16 #include <time.h>
17 #include <sys/ptrace.h>
18 #include <sys/ioctl.h>
19 #include <sys/uio.h>
20 #include <sys/types.h>
21 #include <sys/wait.h>
22 #include <sys/signal.h>
23 #include <sys/ipc.h>
24 #include <sys/shm.h>
25 #include <sys/user.h>
26 #include <sys/syscall.h>
27 #include <linux/elf.h>
28 #include <linux/types.h>
29 #include <linux/auxvec.h>
30 #include "reg.h"
31 #include "utils.h"
32
33 #define TEST_PASS 0
34 #define TEST_FAIL 1
35
36 struct fpr_regs {
37 __u64 fpr[32];
38 __u64 fpscr;
39 };
40
41 struct tm_spr_regs {
42 unsigned long tm_tfhar;
43 unsigned long tm_texasr;
44 unsigned long tm_tfiar;
45 };
46
47 #ifndef NT_PPC_TAR
48 #define NT_PPC_TAR 0x103
49 #define NT_PPC_PPR 0x104
50 #define NT_PPC_DSCR 0x105
51 #define NT_PPC_EBB 0x106
52 #define NT_PPC_PMU 0x107
53 #define NT_PPC_TM_CGPR 0x108
54 #define NT_PPC_TM_CFPR 0x109
55 #define NT_PPC_TM_CVMX 0x10a
56 #define NT_PPC_TM_CVSX 0x10b
57 #define NT_PPC_TM_SPR 0x10c
58 #define NT_PPC_TM_CTAR 0x10d
59 #define NT_PPC_TM_CPPR 0x10e
60 #define NT_PPC_TM_CDSCR 0x10f
61 #endif
62
63 /* Basic ptrace operations */
start_trace(pid_t child)64 int start_trace(pid_t child)
65 {
66 int ret;
67
68 ret = ptrace(PTRACE_ATTACH, child, NULL, NULL);
69 if (ret) {
70 perror("ptrace(PTRACE_ATTACH) failed");
71 return TEST_FAIL;
72 }
73 ret = waitpid(child, NULL, 0);
74 if (ret != child) {
75 perror("waitpid() failed");
76 return TEST_FAIL;
77 }
78 return TEST_PASS;
79 }
80
stop_trace(pid_t child)81 int stop_trace(pid_t child)
82 {
83 int ret;
84
85 ret = ptrace(PTRACE_DETACH, child, NULL, NULL);
86 if (ret) {
87 perror("ptrace(PTRACE_DETACH) failed");
88 return TEST_FAIL;
89 }
90 return TEST_PASS;
91 }
92
cont_trace(pid_t child)93 int cont_trace(pid_t child)
94 {
95 int ret;
96
97 ret = ptrace(PTRACE_CONT, child, NULL, NULL);
98 if (ret) {
99 perror("ptrace(PTRACE_CONT) failed");
100 return TEST_FAIL;
101 }
102 return TEST_PASS;
103 }
104
ptrace_read_regs(pid_t child,unsigned long type,unsigned long regs[],int n)105 int ptrace_read_regs(pid_t child, unsigned long type, unsigned long regs[],
106 int n)
107 {
108 struct iovec iov;
109 long ret;
110
111 FAIL_IF(start_trace(child));
112
113 iov.iov_base = regs;
114 iov.iov_len = n * sizeof(unsigned long);
115
116 ret = ptrace(PTRACE_GETREGSET, child, type, &iov);
117 if (ret)
118 return ret;
119
120 FAIL_IF(stop_trace(child));
121
122 return TEST_PASS;
123 }
124
ptrace_write_regs(pid_t child,unsigned long type,unsigned long regs[],int n)125 long ptrace_write_regs(pid_t child, unsigned long type, unsigned long regs[],
126 int n)
127 {
128 struct iovec iov;
129 long ret;
130
131 FAIL_IF(start_trace(child));
132
133 iov.iov_base = regs;
134 iov.iov_len = n * sizeof(unsigned long);
135
136 ret = ptrace(PTRACE_SETREGSET, child, type, &iov);
137
138 FAIL_IF(stop_trace(child));
139
140 return ret;
141 }
142
143 /* TAR, PPR, DSCR */
show_tar_registers(pid_t child,unsigned long * out)144 int show_tar_registers(pid_t child, unsigned long *out)
145 {
146 struct iovec iov;
147 unsigned long *reg;
148 int ret;
149
150 reg = malloc(sizeof(unsigned long));
151 if (!reg) {
152 perror("malloc() failed");
153 return TEST_FAIL;
154 }
155 iov.iov_base = (u64 *) reg;
156 iov.iov_len = sizeof(unsigned long);
157
158 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TAR, &iov);
159 if (ret) {
160 perror("ptrace(PTRACE_GETREGSET) failed");
161 goto fail;
162 }
163 if (out)
164 out[0] = *reg;
165
166 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_PPR, &iov);
167 if (ret) {
168 perror("ptrace(PTRACE_GETREGSET) failed");
169 goto fail;
170 }
171 if (out)
172 out[1] = *reg;
173
174 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_DSCR, &iov);
175 if (ret) {
176 perror("ptrace(PTRACE_GETREGSET) failed");
177 goto fail;
178 }
179 if (out)
180 out[2] = *reg;
181
182 free(reg);
183 return TEST_PASS;
184 fail:
185 free(reg);
186 return TEST_FAIL;
187 }
188
write_tar_registers(pid_t child,unsigned long tar,unsigned long ppr,unsigned long dscr)189 int write_tar_registers(pid_t child, unsigned long tar,
190 unsigned long ppr, unsigned long dscr)
191 {
192 struct iovec iov;
193 unsigned long *reg;
194 int ret;
195
196 reg = malloc(sizeof(unsigned long));
197 if (!reg) {
198 perror("malloc() failed");
199 return TEST_FAIL;
200 }
201
202 iov.iov_base = (u64 *) reg;
203 iov.iov_len = sizeof(unsigned long);
204
205 *reg = tar;
206 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TAR, &iov);
207 if (ret) {
208 perror("ptrace(PTRACE_SETREGSET) failed");
209 goto fail;
210 }
211
212 *reg = ppr;
213 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_PPR, &iov);
214 if (ret) {
215 perror("ptrace(PTRACE_SETREGSET) failed");
216 goto fail;
217 }
218
219 *reg = dscr;
220 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_DSCR, &iov);
221 if (ret) {
222 perror("ptrace(PTRACE_SETREGSET) failed");
223 goto fail;
224 }
225
226 free(reg);
227 return TEST_PASS;
228 fail:
229 free(reg);
230 return TEST_FAIL;
231 }
232
show_tm_checkpointed_state(pid_t child,unsigned long * out)233 int show_tm_checkpointed_state(pid_t child, unsigned long *out)
234 {
235 struct iovec iov;
236 unsigned long *reg;
237 int ret;
238
239 reg = malloc(sizeof(unsigned long));
240 if (!reg) {
241 perror("malloc() failed");
242 return TEST_FAIL;
243 }
244
245 iov.iov_base = (u64 *) reg;
246 iov.iov_len = sizeof(unsigned long);
247
248 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CTAR, &iov);
249 if (ret) {
250 perror("ptrace(PTRACE_GETREGSET) failed");
251 goto fail;
252 }
253 if (out)
254 out[0] = *reg;
255
256 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CPPR, &iov);
257 if (ret) {
258 perror("ptrace(PTRACE_GETREGSET) failed");
259 goto fail;
260 }
261 if (out)
262 out[1] = *reg;
263
264 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CDSCR, &iov);
265 if (ret) {
266 perror("ptrace(PTRACE_GETREGSET) failed");
267 goto fail;
268 }
269 if (out)
270 out[2] = *reg;
271
272 free(reg);
273 return TEST_PASS;
274
275 fail:
276 free(reg);
277 return TEST_FAIL;
278 }
279
write_ckpt_tar_registers(pid_t child,unsigned long tar,unsigned long ppr,unsigned long dscr)280 int write_ckpt_tar_registers(pid_t child, unsigned long tar,
281 unsigned long ppr, unsigned long dscr)
282 {
283 struct iovec iov;
284 unsigned long *reg;
285 int ret;
286
287 reg = malloc(sizeof(unsigned long));
288 if (!reg) {
289 perror("malloc() failed");
290 return TEST_FAIL;
291 }
292
293 iov.iov_base = (u64 *) reg;
294 iov.iov_len = sizeof(unsigned long);
295
296 *reg = tar;
297 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CTAR, &iov);
298 if (ret) {
299 perror("ptrace(PTRACE_GETREGSET) failed");
300 goto fail;
301 }
302
303 *reg = ppr;
304 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CPPR, &iov);
305 if (ret) {
306 perror("ptrace(PTRACE_GETREGSET) failed");
307 goto fail;
308 }
309
310 *reg = dscr;
311 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CDSCR, &iov);
312 if (ret) {
313 perror("ptrace(PTRACE_GETREGSET) failed");
314 goto fail;
315 }
316
317 free(reg);
318 return TEST_PASS;
319 fail:
320 free(reg);
321 return TEST_FAIL;
322 }
323
324 /* FPR */
show_fpr(pid_t child,__u64 * fpr)325 int show_fpr(pid_t child, __u64 *fpr)
326 {
327 struct fpr_regs *regs;
328 int ret, i;
329
330 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
331 ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs);
332 if (ret) {
333 perror("ptrace(PTRACE_GETREGSET) failed");
334 return TEST_FAIL;
335 }
336
337 if (fpr) {
338 for (i = 0; i < 32; i++)
339 fpr[i] = regs->fpr[i];
340 }
341 return TEST_PASS;
342 }
343
write_fpr(pid_t child,__u64 val)344 int write_fpr(pid_t child, __u64 val)
345 {
346 struct fpr_regs *regs;
347 int ret, i;
348
349 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
350 ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs);
351 if (ret) {
352 perror("ptrace(PTRACE_GETREGSET) failed");
353 return TEST_FAIL;
354 }
355
356 for (i = 0; i < 32; i++)
357 regs->fpr[i] = val;
358
359 ret = ptrace(PTRACE_SETFPREGS, child, NULL, regs);
360 if (ret) {
361 perror("ptrace(PTRACE_GETREGSET) failed");
362 return TEST_FAIL;
363 }
364 return TEST_PASS;
365 }
366
show_ckpt_fpr(pid_t child,__u64 * fpr)367 int show_ckpt_fpr(pid_t child, __u64 *fpr)
368 {
369 struct fpr_regs *regs;
370 struct iovec iov;
371 int ret, i;
372
373 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
374 iov.iov_base = regs;
375 iov.iov_len = sizeof(struct fpr_regs);
376
377 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov);
378 if (ret) {
379 perror("ptrace(PTRACE_GETREGSET) failed");
380 return TEST_FAIL;
381 }
382
383 if (fpr) {
384 for (i = 0; i < 32; i++)
385 fpr[i] = regs->fpr[i];
386 }
387
388 return TEST_PASS;
389 }
390
write_ckpt_fpr(pid_t child,unsigned long val)391 int write_ckpt_fpr(pid_t child, unsigned long val)
392 {
393 struct fpr_regs *regs;
394 struct iovec iov;
395 int ret, i;
396
397 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
398 iov.iov_base = regs;
399 iov.iov_len = sizeof(struct fpr_regs);
400
401 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov);
402 if (ret) {
403 perror("ptrace(PTRACE_GETREGSET) failed");
404 return TEST_FAIL;
405 }
406
407 for (i = 0; i < 32; i++)
408 regs->fpr[i] = val;
409
410 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CFPR, &iov);
411 if (ret) {
412 perror("ptrace(PTRACE_GETREGSET) failed");
413 return TEST_FAIL;
414 }
415 return TEST_PASS;
416 }
417
418 /* GPR */
show_gpr(pid_t child,unsigned long * gpr)419 int show_gpr(pid_t child, unsigned long *gpr)
420 {
421 struct pt_regs *regs;
422 int ret, i;
423
424 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
425 if (!regs) {
426 perror("malloc() failed");
427 return TEST_FAIL;
428 }
429
430 ret = ptrace(PTRACE_GETREGS, child, NULL, regs);
431 if (ret) {
432 perror("ptrace(PTRACE_GETREGSET) failed");
433 return TEST_FAIL;
434 }
435
436 if (gpr) {
437 for (i = 14; i < 32; i++)
438 gpr[i-14] = regs->gpr[i];
439 }
440
441 return TEST_PASS;
442 }
443
sys_ptrace(enum __ptrace_request request,pid_t pid,unsigned long addr,unsigned long data)444 long sys_ptrace(enum __ptrace_request request, pid_t pid, unsigned long addr, unsigned long data)
445 {
446 return syscall(__NR_ptrace, request, pid, (void *)addr, data);
447 }
448
449 // 33 because of FPSCR
450 #define PT_NUM_FPRS (33 * (sizeof(__u64) / sizeof(unsigned long)))
451
peek_fprs(pid_t child)452 __u64 *peek_fprs(pid_t child)
453 {
454 unsigned long *fprs, *p, addr;
455 long ret;
456 int i;
457
458 fprs = malloc(sizeof(unsigned long) * PT_NUM_FPRS);
459 if (!fprs) {
460 perror("malloc() failed");
461 return NULL;
462 }
463
464 for (i = 0, p = fprs; i < PT_NUM_FPRS; i++, p++) {
465 addr = sizeof(unsigned long) * (PT_FPR0 + i);
466 ret = sys_ptrace(PTRACE_PEEKUSER, child, addr, (unsigned long)p);
467 if (ret) {
468 perror("ptrace(PTRACE_PEEKUSR) failed");
469 return NULL;
470 }
471 }
472
473 addr = sizeof(unsigned long) * (PT_FPR0 + i);
474 ret = sys_ptrace(PTRACE_PEEKUSER, child, addr, (unsigned long)&addr);
475 if (!ret) {
476 printf("ptrace(PTRACE_PEEKUSR) succeeded unexpectedly!\n");
477 return NULL;
478 }
479
480 return (__u64 *)fprs;
481 }
482
poke_fprs(pid_t child,unsigned long * fprs)483 int poke_fprs(pid_t child, unsigned long *fprs)
484 {
485 unsigned long *p, addr;
486 long ret;
487 int i;
488
489 for (i = 0, p = fprs; i < PT_NUM_FPRS; i++, p++) {
490 addr = sizeof(unsigned long) * (PT_FPR0 + i);
491 ret = sys_ptrace(PTRACE_POKEUSER, child, addr, *p);
492 if (ret) {
493 perror("ptrace(PTRACE_POKEUSR) failed");
494 return -1;
495 }
496 }
497
498 addr = sizeof(unsigned long) * (PT_FPR0 + i);
499 ret = sys_ptrace(PTRACE_POKEUSER, child, addr, addr);
500 if (!ret) {
501 printf("ptrace(PTRACE_POKEUSR) succeeded unexpectedly!\n");
502 return -1;
503 }
504
505 return 0;
506 }
507
write_gpr(pid_t child,unsigned long val)508 int write_gpr(pid_t child, unsigned long val)
509 {
510 struct pt_regs *regs;
511 int i, ret;
512
513 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
514 if (!regs) {
515 perror("malloc() failed");
516 return TEST_FAIL;
517 }
518
519 ret = ptrace(PTRACE_GETREGS, child, NULL, regs);
520 if (ret) {
521 perror("ptrace(PTRACE_GETREGSET) failed");
522 return TEST_FAIL;
523 }
524
525 for (i = 14; i < 32; i++)
526 regs->gpr[i] = val;
527
528 ret = ptrace(PTRACE_SETREGS, child, NULL, regs);
529 if (ret) {
530 perror("ptrace(PTRACE_GETREGSET) failed");
531 return TEST_FAIL;
532 }
533 return TEST_PASS;
534 }
535
show_ckpt_gpr(pid_t child,unsigned long * gpr)536 int show_ckpt_gpr(pid_t child, unsigned long *gpr)
537 {
538 struct pt_regs *regs;
539 struct iovec iov;
540 int ret, i;
541
542 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
543 if (!regs) {
544 perror("malloc() failed");
545 return TEST_FAIL;
546 }
547
548 iov.iov_base = (u64 *) regs;
549 iov.iov_len = sizeof(struct pt_regs);
550
551 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov);
552 if (ret) {
553 perror("ptrace(PTRACE_GETREGSET) failed");
554 return TEST_FAIL;
555 }
556
557 if (gpr) {
558 for (i = 14; i < 32; i++)
559 gpr[i-14] = regs->gpr[i];
560 }
561
562 return TEST_PASS;
563 }
564
write_ckpt_gpr(pid_t child,unsigned long val)565 int write_ckpt_gpr(pid_t child, unsigned long val)
566 {
567 struct pt_regs *regs;
568 struct iovec iov;
569 int ret, i;
570
571 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
572 if (!regs) {
573 perror("malloc() failed\n");
574 return TEST_FAIL;
575 }
576 iov.iov_base = (u64 *) regs;
577 iov.iov_len = sizeof(struct pt_regs);
578
579 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov);
580 if (ret) {
581 perror("ptrace(PTRACE_GETREGSET) failed");
582 return TEST_FAIL;
583 }
584
585 for (i = 14; i < 32; i++)
586 regs->gpr[i] = val;
587
588 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CGPR, &iov);
589 if (ret) {
590 perror("ptrace(PTRACE_GETREGSET) failed");
591 return TEST_FAIL;
592 }
593 return TEST_PASS;
594 }
595
596 /* VMX */
show_vmx(pid_t child,unsigned long vmx[][2])597 int show_vmx(pid_t child, unsigned long vmx[][2])
598 {
599 int ret;
600
601 ret = ptrace(PTRACE_GETVRREGS, child, 0, vmx);
602 if (ret) {
603 perror("ptrace(PTRACE_GETVRREGS) failed");
604 return TEST_FAIL;
605 }
606 return TEST_PASS;
607 }
608
show_vmx_ckpt(pid_t child,unsigned long vmx[][2])609 int show_vmx_ckpt(pid_t child, unsigned long vmx[][2])
610 {
611 unsigned long regs[34][2];
612 struct iovec iov;
613 int ret;
614
615 iov.iov_base = (u64 *) regs;
616 iov.iov_len = sizeof(regs);
617 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVMX, &iov);
618 if (ret) {
619 perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVMX) failed");
620 return TEST_FAIL;
621 }
622 memcpy(vmx, regs, sizeof(regs));
623 return TEST_PASS;
624 }
625
626
write_vmx(pid_t child,unsigned long vmx[][2])627 int write_vmx(pid_t child, unsigned long vmx[][2])
628 {
629 int ret;
630
631 ret = ptrace(PTRACE_SETVRREGS, child, 0, vmx);
632 if (ret) {
633 perror("ptrace(PTRACE_SETVRREGS) failed");
634 return TEST_FAIL;
635 }
636 return TEST_PASS;
637 }
638
write_vmx_ckpt(pid_t child,unsigned long vmx[][2])639 int write_vmx_ckpt(pid_t child, unsigned long vmx[][2])
640 {
641 unsigned long regs[34][2];
642 struct iovec iov;
643 int ret;
644
645 memcpy(regs, vmx, sizeof(regs));
646 iov.iov_base = (u64 *) regs;
647 iov.iov_len = sizeof(regs);
648 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CVMX, &iov);
649 if (ret) {
650 perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVMX) failed");
651 return TEST_FAIL;
652 }
653 return TEST_PASS;
654 }
655
656 /* VSX */
show_vsx(pid_t child,unsigned long * vsx)657 int show_vsx(pid_t child, unsigned long *vsx)
658 {
659 int ret;
660
661 ret = ptrace(PTRACE_GETVSRREGS, child, 0, vsx);
662 if (ret) {
663 perror("ptrace(PTRACE_GETVSRREGS) failed");
664 return TEST_FAIL;
665 }
666 return TEST_PASS;
667 }
668
show_vsx_ckpt(pid_t child,unsigned long * vsx)669 int show_vsx_ckpt(pid_t child, unsigned long *vsx)
670 {
671 unsigned long regs[32];
672 struct iovec iov;
673 int ret;
674
675 iov.iov_base = (u64 *) regs;
676 iov.iov_len = sizeof(regs);
677 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVSX, &iov);
678 if (ret) {
679 perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVSX) failed");
680 return TEST_FAIL;
681 }
682 memcpy(vsx, regs, sizeof(regs));
683 return TEST_PASS;
684 }
685
write_vsx(pid_t child,unsigned long * vsx)686 int write_vsx(pid_t child, unsigned long *vsx)
687 {
688 int ret;
689
690 ret = ptrace(PTRACE_SETVSRREGS, child, 0, vsx);
691 if (ret) {
692 perror("ptrace(PTRACE_SETVSRREGS) failed");
693 return TEST_FAIL;
694 }
695 return TEST_PASS;
696 }
697
write_vsx_ckpt(pid_t child,unsigned long * vsx)698 int write_vsx_ckpt(pid_t child, unsigned long *vsx)
699 {
700 unsigned long regs[32];
701 struct iovec iov;
702 int ret;
703
704 memcpy(regs, vsx, sizeof(regs));
705 iov.iov_base = (u64 *) regs;
706 iov.iov_len = sizeof(regs);
707 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CVSX, &iov);
708 if (ret) {
709 perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVSX) failed");
710 return TEST_FAIL;
711 }
712 return TEST_PASS;
713 }
714
715 /* TM SPR */
show_tm_spr(pid_t child,struct tm_spr_regs * out)716 int show_tm_spr(pid_t child, struct tm_spr_regs *out)
717 {
718 struct tm_spr_regs *regs;
719 struct iovec iov;
720 int ret;
721
722 regs = (struct tm_spr_regs *) malloc(sizeof(struct tm_spr_regs));
723 if (!regs) {
724 perror("malloc() failed");
725 return TEST_FAIL;
726 }
727
728 iov.iov_base = (u64 *) regs;
729 iov.iov_len = sizeof(struct tm_spr_regs);
730
731 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_SPR, &iov);
732 if (ret) {
733 perror("ptrace(PTRACE_GETREGSET) failed");
734 return TEST_FAIL;
735 }
736
737 if (out)
738 memcpy(out, regs, sizeof(struct tm_spr_regs));
739
740 return TEST_PASS;
741 }
742
743
744
745 /* Analyse TEXASR after TM failure */
get_tfiar(void)746 inline unsigned long get_tfiar(void)
747 {
748 return mfspr(SPRN_TFIAR);
749 }
750
analyse_texasr(unsigned long texasr)751 void analyse_texasr(unsigned long texasr)
752 {
753 printf("TEXASR: %16lx\t", texasr);
754
755 if (texasr & TEXASR_FP)
756 printf("TEXASR_FP ");
757
758 if (texasr & TEXASR_DA)
759 printf("TEXASR_DA ");
760
761 if (texasr & TEXASR_NO)
762 printf("TEXASR_NO ");
763
764 if (texasr & TEXASR_FO)
765 printf("TEXASR_FO ");
766
767 if (texasr & TEXASR_SIC)
768 printf("TEXASR_SIC ");
769
770 if (texasr & TEXASR_NTC)
771 printf("TEXASR_NTC ");
772
773 if (texasr & TEXASR_TC)
774 printf("TEXASR_TC ");
775
776 if (texasr & TEXASR_TIC)
777 printf("TEXASR_TIC ");
778
779 if (texasr & TEXASR_IC)
780 printf("TEXASR_IC ");
781
782 if (texasr & TEXASR_IFC)
783 printf("TEXASR_IFC ");
784
785 if (texasr & TEXASR_ABT)
786 printf("TEXASR_ABT ");
787
788 if (texasr & TEXASR_SPD)
789 printf("TEXASR_SPD ");
790
791 if (texasr & TEXASR_HV)
792 printf("TEXASR_HV ");
793
794 if (texasr & TEXASR_PR)
795 printf("TEXASR_PR ");
796
797 if (texasr & TEXASR_FS)
798 printf("TEXASR_FS ");
799
800 if (texasr & TEXASR_TE)
801 printf("TEXASR_TE ");
802
803 if (texasr & TEXASR_ROT)
804 printf("TEXASR_ROT ");
805
806 printf("TFIAR :%lx\n", get_tfiar());
807 }
808
809 void store_gpr(unsigned long *addr);
810