]>
git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blob - tools/testing/selftests/powerpc/ptrace/ptrace.h
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 * Ptrace interface test helper functions
5 * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
14 #include <sys/ptrace.h>
15 #include <sys/ioctl.h>
17 #include <sys/types.h>
19 #include <sys/signal.h>
23 #include <linux/elf.h>
24 #include <linux/types.h>
25 #include <linux/auxvec.h>
33 unsigned long fpr
[32];
38 unsigned long tm_tfhar
;
39 unsigned long tm_texasr
;
40 unsigned long tm_tfiar
;
44 #define NT_PPC_TAR 0x103
45 #define NT_PPC_PPR 0x104
46 #define NT_PPC_DSCR 0x105
47 #define NT_PPC_EBB 0x106
48 #define NT_PPC_PMU 0x107
49 #define NT_PPC_TM_CGPR 0x108
50 #define NT_PPC_TM_CFPR 0x109
51 #define NT_PPC_TM_CVMX 0x10a
52 #define NT_PPC_TM_CVSX 0x10b
53 #define NT_PPC_TM_SPR 0x10c
54 #define NT_PPC_TM_CTAR 0x10d
55 #define NT_PPC_TM_CPPR 0x10e
56 #define NT_PPC_TM_CDSCR 0x10f
59 /* Basic ptrace operations */
60 int start_trace(pid_t child
)
64 ret
= ptrace(PTRACE_ATTACH
, child
, NULL
, NULL
);
66 perror("ptrace(PTRACE_ATTACH) failed");
69 ret
= waitpid(child
, NULL
, 0);
71 perror("waitpid() failed");
77 int stop_trace(pid_t child
)
81 ret
= ptrace(PTRACE_DETACH
, child
, NULL
, NULL
);
83 perror("ptrace(PTRACE_DETACH) failed");
89 int cont_trace(pid_t child
)
93 ret
= ptrace(PTRACE_CONT
, child
, NULL
, NULL
);
95 perror("ptrace(PTRACE_CONT) failed");
101 int ptrace_read_regs(pid_t child
, unsigned long type
, unsigned long regs
[],
107 FAIL_IF(start_trace(child
));
110 iov
.iov_len
= n
* sizeof(unsigned long);
112 ret
= ptrace(PTRACE_GETREGSET
, child
, type
, &iov
);
116 FAIL_IF(stop_trace(child
));
121 long ptrace_write_regs(pid_t child
, unsigned long type
, unsigned long regs
[],
127 FAIL_IF(start_trace(child
));
130 iov
.iov_len
= n
* sizeof(unsigned long);
132 ret
= ptrace(PTRACE_SETREGSET
, child
, type
, &iov
);
134 FAIL_IF(stop_trace(child
));
140 int show_tar_registers(pid_t child
, unsigned long *out
)
146 reg
= malloc(sizeof(unsigned long));
148 perror("malloc() failed");
151 iov
.iov_base
= (u64
*) reg
;
152 iov
.iov_len
= sizeof(unsigned long);
154 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_TAR
, &iov
);
156 perror("ptrace(PTRACE_GETREGSET) failed");
162 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_PPR
, &iov
);
164 perror("ptrace(PTRACE_GETREGSET) failed");
170 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_DSCR
, &iov
);
172 perror("ptrace(PTRACE_GETREGSET) failed");
185 int write_tar_registers(pid_t child
, unsigned long tar
,
186 unsigned long ppr
, unsigned long dscr
)
192 reg
= malloc(sizeof(unsigned long));
194 perror("malloc() failed");
198 iov
.iov_base
= (u64
*) reg
;
199 iov
.iov_len
= sizeof(unsigned long);
202 ret
= ptrace(PTRACE_SETREGSET
, child
, NT_PPC_TAR
, &iov
);
204 perror("ptrace(PTRACE_SETREGSET) failed");
209 ret
= ptrace(PTRACE_SETREGSET
, child
, NT_PPC_PPR
, &iov
);
211 perror("ptrace(PTRACE_SETREGSET) failed");
216 ret
= ptrace(PTRACE_SETREGSET
, child
, NT_PPC_DSCR
, &iov
);
218 perror("ptrace(PTRACE_SETREGSET) failed");
229 int show_tm_checkpointed_state(pid_t child
, unsigned long *out
)
235 reg
= malloc(sizeof(unsigned long));
237 perror("malloc() failed");
241 iov
.iov_base
= (u64
*) reg
;
242 iov
.iov_len
= sizeof(unsigned long);
244 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_TM_CTAR
, &iov
);
246 perror("ptrace(PTRACE_GETREGSET) failed");
252 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_TM_CPPR
, &iov
);
254 perror("ptrace(PTRACE_GETREGSET) failed");
260 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_TM_CDSCR
, &iov
);
262 perror("ptrace(PTRACE_GETREGSET) failed");
276 int write_ckpt_tar_registers(pid_t child
, unsigned long tar
,
277 unsigned long ppr
, unsigned long dscr
)
283 reg
= malloc(sizeof(unsigned long));
285 perror("malloc() failed");
289 iov
.iov_base
= (u64
*) reg
;
290 iov
.iov_len
= sizeof(unsigned long);
293 ret
= ptrace(PTRACE_SETREGSET
, child
, NT_PPC_TM_CTAR
, &iov
);
295 perror("ptrace(PTRACE_GETREGSET) failed");
300 ret
= ptrace(PTRACE_SETREGSET
, child
, NT_PPC_TM_CPPR
, &iov
);
302 perror("ptrace(PTRACE_GETREGSET) failed");
307 ret
= ptrace(PTRACE_SETREGSET
, child
, NT_PPC_TM_CDSCR
, &iov
);
309 perror("ptrace(PTRACE_GETREGSET) failed");
321 int show_fpr(pid_t child
, unsigned long *fpr
)
323 struct fpr_regs
*regs
;
326 regs
= (struct fpr_regs
*) malloc(sizeof(struct fpr_regs
));
327 ret
= ptrace(PTRACE_GETFPREGS
, child
, NULL
, regs
);
329 perror("ptrace(PTRACE_GETREGSET) failed");
334 for (i
= 0; i
< 32; i
++)
335 fpr
[i
] = regs
->fpr
[i
];
340 int write_fpr(pid_t child
, unsigned long val
)
342 struct fpr_regs
*regs
;
345 regs
= (struct fpr_regs
*) malloc(sizeof(struct fpr_regs
));
346 ret
= ptrace(PTRACE_GETFPREGS
, child
, NULL
, regs
);
348 perror("ptrace(PTRACE_GETREGSET) failed");
352 for (i
= 0; i
< 32; i
++)
355 ret
= ptrace(PTRACE_SETFPREGS
, child
, NULL
, regs
);
357 perror("ptrace(PTRACE_GETREGSET) failed");
363 int show_ckpt_fpr(pid_t child
, unsigned long *fpr
)
365 struct fpr_regs
*regs
;
369 regs
= (struct fpr_regs
*) malloc(sizeof(struct fpr_regs
));
371 iov
.iov_len
= sizeof(struct fpr_regs
);
373 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_TM_CFPR
, &iov
);
375 perror("ptrace(PTRACE_GETREGSET) failed");
380 for (i
= 0; i
< 32; i
++)
381 fpr
[i
] = regs
->fpr
[i
];
387 int write_ckpt_fpr(pid_t child
, unsigned long val
)
389 struct fpr_regs
*regs
;
393 regs
= (struct fpr_regs
*) malloc(sizeof(struct fpr_regs
));
395 iov
.iov_len
= sizeof(struct fpr_regs
);
397 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_TM_CFPR
, &iov
);
399 perror("ptrace(PTRACE_GETREGSET) failed");
403 for (i
= 0; i
< 32; i
++)
406 ret
= ptrace(PTRACE_SETREGSET
, child
, NT_PPC_TM_CFPR
, &iov
);
408 perror("ptrace(PTRACE_GETREGSET) failed");
415 int show_gpr(pid_t child
, unsigned long *gpr
)
417 struct pt_regs
*regs
;
420 regs
= (struct pt_regs
*) malloc(sizeof(struct pt_regs
));
422 perror("malloc() failed");
426 ret
= ptrace(PTRACE_GETREGS
, child
, NULL
, regs
);
428 perror("ptrace(PTRACE_GETREGSET) failed");
433 for (i
= 14; i
< 32; i
++)
434 gpr
[i
-14] = regs
->gpr
[i
];
440 int write_gpr(pid_t child
, unsigned long val
)
442 struct pt_regs
*regs
;
445 regs
= (struct pt_regs
*) malloc(sizeof(struct pt_regs
));
447 perror("malloc() failed");
451 ret
= ptrace(PTRACE_GETREGS
, child
, NULL
, regs
);
453 perror("ptrace(PTRACE_GETREGSET) failed");
457 for (i
= 14; i
< 32; i
++)
460 ret
= ptrace(PTRACE_SETREGS
, child
, NULL
, regs
);
462 perror("ptrace(PTRACE_GETREGSET) failed");
468 int show_ckpt_gpr(pid_t child
, unsigned long *gpr
)
470 struct pt_regs
*regs
;
474 regs
= (struct pt_regs
*) malloc(sizeof(struct pt_regs
));
476 perror("malloc() failed");
480 iov
.iov_base
= (u64
*) regs
;
481 iov
.iov_len
= sizeof(struct pt_regs
);
483 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_TM_CGPR
, &iov
);
485 perror("ptrace(PTRACE_GETREGSET) failed");
490 for (i
= 14; i
< 32; i
++)
491 gpr
[i
-14] = regs
->gpr
[i
];
497 int write_ckpt_gpr(pid_t child
, unsigned long val
)
499 struct pt_regs
*regs
;
503 regs
= (struct pt_regs
*) malloc(sizeof(struct pt_regs
));
505 perror("malloc() failed\n");
508 iov
.iov_base
= (u64
*) regs
;
509 iov
.iov_len
= sizeof(struct pt_regs
);
511 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_TM_CGPR
, &iov
);
513 perror("ptrace(PTRACE_GETREGSET) failed");
517 for (i
= 14; i
< 32; i
++)
520 ret
= ptrace(PTRACE_SETREGSET
, child
, NT_PPC_TM_CGPR
, &iov
);
522 perror("ptrace(PTRACE_GETREGSET) failed");
529 int show_vmx(pid_t child
, unsigned long vmx
[][2])
533 ret
= ptrace(PTRACE_GETVRREGS
, child
, 0, vmx
);
535 perror("ptrace(PTRACE_GETVRREGS) failed");
541 int show_vmx_ckpt(pid_t child
, unsigned long vmx
[][2])
543 unsigned long regs
[34][2];
547 iov
.iov_base
= (u64
*) regs
;
548 iov
.iov_len
= sizeof(regs
);
549 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_TM_CVMX
, &iov
);
551 perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVMX) failed");
554 memcpy(vmx
, regs
, sizeof(regs
));
559 int write_vmx(pid_t child
, unsigned long vmx
[][2])
563 ret
= ptrace(PTRACE_SETVRREGS
, child
, 0, vmx
);
565 perror("ptrace(PTRACE_SETVRREGS) failed");
571 int write_vmx_ckpt(pid_t child
, unsigned long vmx
[][2])
573 unsigned long regs
[34][2];
577 memcpy(regs
, vmx
, sizeof(regs
));
578 iov
.iov_base
= (u64
*) regs
;
579 iov
.iov_len
= sizeof(regs
);
580 ret
= ptrace(PTRACE_SETREGSET
, child
, NT_PPC_TM_CVMX
, &iov
);
582 perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVMX) failed");
589 int show_vsx(pid_t child
, unsigned long *vsx
)
593 ret
= ptrace(PTRACE_GETVSRREGS
, child
, 0, vsx
);
595 perror("ptrace(PTRACE_GETVSRREGS) failed");
601 int show_vsx_ckpt(pid_t child
, unsigned long *vsx
)
603 unsigned long regs
[32];
607 iov
.iov_base
= (u64
*) regs
;
608 iov
.iov_len
= sizeof(regs
);
609 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_TM_CVSX
, &iov
);
611 perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVSX) failed");
614 memcpy(vsx
, regs
, sizeof(regs
));
618 int write_vsx(pid_t child
, unsigned long *vsx
)
622 ret
= ptrace(PTRACE_SETVSRREGS
, child
, 0, vsx
);
624 perror("ptrace(PTRACE_SETVSRREGS) failed");
630 int write_vsx_ckpt(pid_t child
, unsigned long *vsx
)
632 unsigned long regs
[32];
636 memcpy(regs
, vsx
, sizeof(regs
));
637 iov
.iov_base
= (u64
*) regs
;
638 iov
.iov_len
= sizeof(regs
);
639 ret
= ptrace(PTRACE_SETREGSET
, child
, NT_PPC_TM_CVSX
, &iov
);
641 perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVSX) failed");
648 int show_tm_spr(pid_t child
, struct tm_spr_regs
*out
)
650 struct tm_spr_regs
*regs
;
654 regs
= (struct tm_spr_regs
*) malloc(sizeof(struct tm_spr_regs
));
656 perror("malloc() failed");
660 iov
.iov_base
= (u64
*) regs
;
661 iov
.iov_len
= sizeof(struct tm_spr_regs
);
663 ret
= ptrace(PTRACE_GETREGSET
, child
, NT_PPC_TM_SPR
, &iov
);
665 perror("ptrace(PTRACE_GETREGSET) failed");
670 memcpy(out
, regs
, sizeof(struct tm_spr_regs
));
677 /* Analyse TEXASR after TM failure */
678 inline unsigned long get_tfiar(void)
682 asm volatile("mfspr %0,%1" : "=r" (ret
) : "i" (SPRN_TFIAR
));
686 void analyse_texasr(unsigned long texasr
)
688 printf("TEXASR: %16lx\t", texasr
);
690 if (texasr
& TEXASR_FP
)
691 printf("TEXASR_FP ");
693 if (texasr
& TEXASR_DA
)
694 printf("TEXASR_DA ");
696 if (texasr
& TEXASR_NO
)
697 printf("TEXASR_NO ");
699 if (texasr
& TEXASR_FO
)
700 printf("TEXASR_FO ");
702 if (texasr
& TEXASR_SIC
)
703 printf("TEXASR_SIC ");
705 if (texasr
& TEXASR_NTC
)
706 printf("TEXASR_NTC ");
708 if (texasr
& TEXASR_TC
)
709 printf("TEXASR_TC ");
711 if (texasr
& TEXASR_TIC
)
712 printf("TEXASR_TIC ");
714 if (texasr
& TEXASR_IC
)
715 printf("TEXASR_IC ");
717 if (texasr
& TEXASR_IFC
)
718 printf("TEXASR_IFC ");
720 if (texasr
& TEXASR_ABT
)
721 printf("TEXASR_ABT ");
723 if (texasr
& TEXASR_SPD
)
724 printf("TEXASR_SPD ");
726 if (texasr
& TEXASR_HV
)
727 printf("TEXASR_HV ");
729 if (texasr
& TEXASR_PR
)
730 printf("TEXASR_PR ");
732 if (texasr
& TEXASR_FS
)
733 printf("TEXASR_FS ");
735 if (texasr
& TEXASR_TE
)
736 printf("TEXASR_TE ");
738 if (texasr
& TEXASR_ROT
)
739 printf("TEXASR_ROT ");
741 printf("TFIAR :%lx\n", get_tfiar());
744 void store_gpr(unsigned long *addr
);
745 void store_fpr(float *addr
);