Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * Ptrace interface test helper functions
0004  *
0005  * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
0006  */
0007 
0008 #define __SANE_USERSPACE_TYPES__
0009 
0010 #include <inttypes.h>
0011 #include <unistd.h>
0012 #include <stdlib.h>
0013 #include <string.h>
0014 #include <malloc.h>
0015 #include <errno.h>
0016 #include <time.h>
0017 #include <sys/ptrace.h>
0018 #include <sys/ioctl.h>
0019 #include <sys/uio.h>
0020 #include <sys/types.h>
0021 #include <sys/wait.h>
0022 #include <sys/signal.h>
0023 #include <sys/ipc.h>
0024 #include <sys/shm.h>
0025 #include <sys/user.h>
0026 #include <sys/syscall.h>
0027 #include <linux/elf.h>
0028 #include <linux/types.h>
0029 #include <linux/auxvec.h>
0030 #include "reg.h"
0031 #include "utils.h"
0032 
0033 #define TEST_PASS 0
0034 #define TEST_FAIL 1
0035 
0036 struct fpr_regs {
0037     __u64 fpr[32];
0038     __u64 fpscr;
0039 };
0040 
0041 struct tm_spr_regs {
0042     unsigned long tm_tfhar;
0043     unsigned long tm_texasr;
0044     unsigned long tm_tfiar;
0045 };
0046 
0047 #ifndef NT_PPC_TAR
0048 #define NT_PPC_TAR  0x103
0049 #define NT_PPC_PPR  0x104
0050 #define NT_PPC_DSCR 0x105
0051 #define NT_PPC_EBB  0x106
0052 #define NT_PPC_PMU  0x107
0053 #define NT_PPC_TM_CGPR  0x108
0054 #define NT_PPC_TM_CFPR  0x109
0055 #define NT_PPC_TM_CVMX  0x10a
0056 #define NT_PPC_TM_CVSX  0x10b
0057 #define NT_PPC_TM_SPR   0x10c
0058 #define NT_PPC_TM_CTAR  0x10d
0059 #define NT_PPC_TM_CPPR  0x10e
0060 #define NT_PPC_TM_CDSCR 0x10f
0061 #endif
0062 
0063 /* Basic ptrace operations */
0064 int start_trace(pid_t child)
0065 {
0066     int ret;
0067 
0068     ret = ptrace(PTRACE_ATTACH, child, NULL, NULL);
0069     if (ret) {
0070         perror("ptrace(PTRACE_ATTACH) failed");
0071         return TEST_FAIL;
0072     }
0073     ret = waitpid(child, NULL, 0);
0074     if (ret != child) {
0075         perror("waitpid() failed");
0076         return TEST_FAIL;
0077     }
0078     return TEST_PASS;
0079 }
0080 
0081 int stop_trace(pid_t child)
0082 {
0083     int ret;
0084 
0085     ret = ptrace(PTRACE_DETACH, child, NULL, NULL);
0086     if (ret) {
0087         perror("ptrace(PTRACE_DETACH) failed");
0088         return TEST_FAIL;
0089     }
0090     return TEST_PASS;
0091 }
0092 
0093 int cont_trace(pid_t child)
0094 {
0095     int ret;
0096 
0097     ret = ptrace(PTRACE_CONT, child, NULL, NULL);
0098     if (ret) {
0099         perror("ptrace(PTRACE_CONT) failed");
0100         return TEST_FAIL;
0101     }
0102     return TEST_PASS;
0103 }
0104 
0105 int ptrace_read_regs(pid_t child, unsigned long type, unsigned long regs[],
0106              int n)
0107 {
0108     struct iovec iov;
0109     long ret;
0110 
0111     FAIL_IF(start_trace(child));
0112 
0113     iov.iov_base = regs;
0114     iov.iov_len = n * sizeof(unsigned long);
0115 
0116     ret = ptrace(PTRACE_GETREGSET, child, type, &iov);
0117     if (ret)
0118         return ret;
0119 
0120     FAIL_IF(stop_trace(child));
0121 
0122     return TEST_PASS;
0123 }
0124 
0125 long ptrace_write_regs(pid_t child, unsigned long type, unsigned long regs[],
0126                int n)
0127 {
0128     struct iovec iov;
0129     long ret;
0130 
0131     FAIL_IF(start_trace(child));
0132 
0133     iov.iov_base = regs;
0134     iov.iov_len = n * sizeof(unsigned long);
0135 
0136     ret = ptrace(PTRACE_SETREGSET, child, type, &iov);
0137 
0138     FAIL_IF(stop_trace(child));
0139 
0140     return ret;
0141 }
0142 
0143 /* TAR, PPR, DSCR */
0144 int show_tar_registers(pid_t child, unsigned long *out)
0145 {
0146     struct iovec iov;
0147     unsigned long *reg;
0148     int ret;
0149 
0150     reg = malloc(sizeof(unsigned long));
0151     if (!reg) {
0152         perror("malloc() failed");
0153         return TEST_FAIL;
0154     }
0155     iov.iov_base = (u64 *) reg;
0156     iov.iov_len = sizeof(unsigned long);
0157 
0158     ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TAR, &iov);
0159     if (ret) {
0160         perror("ptrace(PTRACE_GETREGSET) failed");
0161         goto fail;
0162     }
0163     if (out)
0164         out[0] = *reg;
0165 
0166     ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_PPR, &iov);
0167     if (ret) {
0168         perror("ptrace(PTRACE_GETREGSET) failed");
0169         goto fail;
0170     }
0171     if (out)
0172         out[1] = *reg;
0173 
0174     ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_DSCR, &iov);
0175     if (ret) {
0176         perror("ptrace(PTRACE_GETREGSET) failed");
0177         goto fail;
0178     }
0179     if (out)
0180         out[2] = *reg;
0181 
0182     free(reg);
0183     return TEST_PASS;
0184 fail:
0185     free(reg);
0186     return TEST_FAIL;
0187 }
0188 
0189 int write_tar_registers(pid_t child, unsigned long tar,
0190         unsigned long ppr, unsigned long dscr)
0191 {
0192     struct iovec iov;
0193     unsigned long *reg;
0194     int ret;
0195 
0196     reg = malloc(sizeof(unsigned long));
0197     if (!reg) {
0198         perror("malloc() failed");
0199         return TEST_FAIL;
0200     }
0201 
0202     iov.iov_base = (u64 *) reg;
0203     iov.iov_len = sizeof(unsigned long);
0204 
0205     *reg = tar;
0206     ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TAR, &iov);
0207     if (ret) {
0208         perror("ptrace(PTRACE_SETREGSET) failed");
0209         goto fail;
0210     }
0211 
0212     *reg = ppr;
0213     ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_PPR, &iov);
0214     if (ret) {
0215         perror("ptrace(PTRACE_SETREGSET) failed");
0216         goto fail;
0217     }
0218 
0219     *reg = dscr;
0220     ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_DSCR, &iov);
0221     if (ret) {
0222         perror("ptrace(PTRACE_SETREGSET) failed");
0223         goto fail;
0224     }
0225 
0226     free(reg);
0227     return TEST_PASS;
0228 fail:
0229     free(reg);
0230     return TEST_FAIL;
0231 }
0232 
0233 int show_tm_checkpointed_state(pid_t child, unsigned long *out)
0234 {
0235     struct iovec iov;
0236     unsigned long *reg;
0237     int ret;
0238 
0239     reg = malloc(sizeof(unsigned long));
0240     if (!reg) {
0241         perror("malloc() failed");
0242         return TEST_FAIL;
0243     }
0244 
0245     iov.iov_base = (u64 *) reg;
0246     iov.iov_len = sizeof(unsigned long);
0247 
0248     ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CTAR, &iov);
0249     if (ret) {
0250         perror("ptrace(PTRACE_GETREGSET) failed");
0251         goto fail;
0252     }
0253     if (out)
0254         out[0] = *reg;
0255 
0256     ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CPPR, &iov);
0257     if (ret) {
0258         perror("ptrace(PTRACE_GETREGSET) failed");
0259         goto fail;
0260     }
0261     if (out)
0262         out[1] = *reg;
0263 
0264     ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CDSCR, &iov);
0265     if (ret) {
0266         perror("ptrace(PTRACE_GETREGSET) failed");
0267         goto fail;
0268     }
0269     if (out)
0270         out[2] = *reg;
0271 
0272     free(reg);
0273     return TEST_PASS;
0274 
0275 fail:
0276     free(reg);
0277     return TEST_FAIL;
0278 }
0279 
0280 int write_ckpt_tar_registers(pid_t child, unsigned long tar,
0281         unsigned long ppr, unsigned long dscr)
0282 {
0283     struct iovec iov;
0284     unsigned long *reg;
0285     int ret;
0286 
0287     reg = malloc(sizeof(unsigned long));
0288     if (!reg) {
0289         perror("malloc() failed");
0290         return TEST_FAIL;
0291     }
0292 
0293     iov.iov_base = (u64 *) reg;
0294     iov.iov_len = sizeof(unsigned long);
0295 
0296     *reg = tar;
0297     ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CTAR, &iov);
0298     if (ret) {
0299         perror("ptrace(PTRACE_GETREGSET) failed");
0300         goto fail;
0301     }
0302 
0303     *reg = ppr;
0304     ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CPPR, &iov);
0305     if (ret) {
0306         perror("ptrace(PTRACE_GETREGSET) failed");
0307         goto fail;
0308     }
0309 
0310     *reg = dscr;
0311     ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CDSCR, &iov);
0312     if (ret) {
0313         perror("ptrace(PTRACE_GETREGSET) failed");
0314         goto fail;
0315     }
0316 
0317     free(reg);
0318     return TEST_PASS;
0319 fail:
0320     free(reg);
0321     return TEST_FAIL;
0322 }
0323 
0324 /* FPR */
0325 int show_fpr(pid_t child, __u64 *fpr)
0326 {
0327     struct fpr_regs *regs;
0328     int ret, i;
0329 
0330     regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
0331     ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs);
0332     if (ret) {
0333         perror("ptrace(PTRACE_GETREGSET) failed");
0334         return TEST_FAIL;
0335     }
0336 
0337     if (fpr) {
0338         for (i = 0; i < 32; i++)
0339             fpr[i] = regs->fpr[i];
0340     }
0341     return TEST_PASS;
0342 }
0343 
0344 int write_fpr(pid_t child, __u64 val)
0345 {
0346     struct fpr_regs *regs;
0347     int ret, i;
0348 
0349     regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
0350     ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs);
0351     if (ret) {
0352         perror("ptrace(PTRACE_GETREGSET) failed");
0353         return TEST_FAIL;
0354     }
0355 
0356     for (i = 0; i < 32; i++)
0357         regs->fpr[i] = val;
0358 
0359     ret = ptrace(PTRACE_SETFPREGS, child, NULL, regs);
0360     if (ret) {
0361         perror("ptrace(PTRACE_GETREGSET) failed");
0362         return TEST_FAIL;
0363     }
0364     return TEST_PASS;
0365 }
0366 
0367 int show_ckpt_fpr(pid_t child, __u64 *fpr)
0368 {
0369     struct fpr_regs *regs;
0370     struct iovec iov;
0371     int ret, i;
0372 
0373     regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
0374     iov.iov_base = regs;
0375     iov.iov_len = sizeof(struct fpr_regs);
0376 
0377     ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov);
0378     if (ret) {
0379         perror("ptrace(PTRACE_GETREGSET) failed");
0380         return TEST_FAIL;
0381     }
0382 
0383     if (fpr) {
0384         for (i = 0; i < 32; i++)
0385             fpr[i] = regs->fpr[i];
0386     }
0387 
0388     return TEST_PASS;
0389 }
0390 
0391 int write_ckpt_fpr(pid_t child, unsigned long val)
0392 {
0393     struct fpr_regs *regs;
0394     struct iovec iov;
0395     int ret, i;
0396 
0397     regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
0398     iov.iov_base = regs;
0399     iov.iov_len = sizeof(struct fpr_regs);
0400 
0401     ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov);
0402     if (ret) {
0403         perror("ptrace(PTRACE_GETREGSET) failed");
0404         return TEST_FAIL;
0405     }
0406 
0407     for (i = 0; i < 32; i++)
0408         regs->fpr[i] = val;
0409 
0410     ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CFPR, &iov);
0411     if (ret) {
0412         perror("ptrace(PTRACE_GETREGSET) failed");
0413         return TEST_FAIL;
0414     }
0415     return TEST_PASS;
0416 }
0417 
0418 /* GPR */
0419 int show_gpr(pid_t child, unsigned long *gpr)
0420 {
0421     struct pt_regs *regs;
0422     int ret, i;
0423 
0424     regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
0425     if (!regs) {
0426         perror("malloc() failed");
0427         return TEST_FAIL;
0428     }
0429 
0430     ret = ptrace(PTRACE_GETREGS, child, NULL, regs);
0431     if (ret) {
0432         perror("ptrace(PTRACE_GETREGSET) failed");
0433         return TEST_FAIL;
0434     }
0435 
0436     if (gpr) {
0437         for (i = 14; i < 32; i++)
0438             gpr[i-14] = regs->gpr[i];
0439     }
0440 
0441     return TEST_PASS;
0442 }
0443 
0444 long sys_ptrace(enum __ptrace_request request, pid_t pid, unsigned long addr, unsigned long data)
0445 {
0446     return syscall(__NR_ptrace, request, pid, (void *)addr, data);
0447 }
0448 
0449 // 33 because of FPSCR
0450 #define PT_NUM_FPRS (33 * (sizeof(__u64) / sizeof(unsigned long)))
0451 
0452 __u64 *peek_fprs(pid_t child)
0453 {
0454     unsigned long *fprs, *p, addr;
0455     long ret;
0456     int i;
0457 
0458     fprs = malloc(sizeof(unsigned long) * PT_NUM_FPRS);
0459     if (!fprs) {
0460         perror("malloc() failed");
0461         return NULL;
0462     }
0463 
0464     for (i = 0, p = fprs; i < PT_NUM_FPRS; i++, p++) {
0465         addr = sizeof(unsigned long) * (PT_FPR0 + i);
0466         ret = sys_ptrace(PTRACE_PEEKUSER, child, addr, (unsigned long)p);
0467         if (ret) {
0468             perror("ptrace(PTRACE_PEEKUSR) failed");
0469             return NULL;
0470         }
0471     }
0472 
0473     addr = sizeof(unsigned long) * (PT_FPR0 + i);
0474     ret = sys_ptrace(PTRACE_PEEKUSER, child, addr, (unsigned long)&addr);
0475     if (!ret) {
0476         printf("ptrace(PTRACE_PEEKUSR) succeeded unexpectedly!\n");
0477         return NULL;
0478     }
0479 
0480     return (__u64 *)fprs;
0481 }
0482 
0483 int poke_fprs(pid_t child, unsigned long *fprs)
0484 {
0485     unsigned long *p, addr;
0486     long ret;
0487     int i;
0488 
0489     for (i = 0, p = fprs; i < PT_NUM_FPRS; i++, p++) {
0490         addr = sizeof(unsigned long) * (PT_FPR0 + i);
0491         ret = sys_ptrace(PTRACE_POKEUSER, child, addr, *p);
0492         if (ret) {
0493             perror("ptrace(PTRACE_POKEUSR) failed");
0494             return -1;
0495         }
0496     }
0497 
0498     addr = sizeof(unsigned long) * (PT_FPR0 + i);
0499     ret = sys_ptrace(PTRACE_POKEUSER, child, addr, addr);
0500     if (!ret) {
0501         printf("ptrace(PTRACE_POKEUSR) succeeded unexpectedly!\n");
0502         return -1;
0503     }
0504 
0505     return 0;
0506 }
0507 
0508 int write_gpr(pid_t child, unsigned long val)
0509 {
0510     struct pt_regs *regs;
0511     int i, ret;
0512 
0513     regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
0514     if (!regs) {
0515         perror("malloc() failed");
0516         return TEST_FAIL;
0517     }
0518 
0519     ret = ptrace(PTRACE_GETREGS, child, NULL, regs);
0520     if (ret) {
0521         perror("ptrace(PTRACE_GETREGSET) failed");
0522         return TEST_FAIL;
0523     }
0524 
0525     for (i = 14; i < 32; i++)
0526         regs->gpr[i] = val;
0527 
0528     ret = ptrace(PTRACE_SETREGS, child, NULL, regs);
0529     if (ret) {
0530         perror("ptrace(PTRACE_GETREGSET) failed");
0531         return TEST_FAIL;
0532     }
0533     return TEST_PASS;
0534 }
0535 
0536 int show_ckpt_gpr(pid_t child, unsigned long *gpr)
0537 {
0538     struct pt_regs *regs;
0539     struct iovec iov;
0540     int ret, i;
0541 
0542     regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
0543     if (!regs) {
0544         perror("malloc() failed");
0545         return TEST_FAIL;
0546     }
0547 
0548     iov.iov_base = (u64 *) regs;
0549     iov.iov_len = sizeof(struct pt_regs);
0550 
0551     ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov);
0552     if (ret) {
0553         perror("ptrace(PTRACE_GETREGSET) failed");
0554         return TEST_FAIL;
0555     }
0556 
0557     if (gpr) {
0558         for (i = 14; i < 32; i++)
0559             gpr[i-14] = regs->gpr[i];
0560     }
0561 
0562     return TEST_PASS;
0563 }
0564 
0565 int write_ckpt_gpr(pid_t child, unsigned long val)
0566 {
0567     struct pt_regs *regs;
0568     struct iovec iov;
0569     int ret, i;
0570 
0571     regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
0572     if (!regs) {
0573         perror("malloc() failed\n");
0574         return TEST_FAIL;
0575     }
0576     iov.iov_base = (u64 *) regs;
0577     iov.iov_len = sizeof(struct pt_regs);
0578 
0579     ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov);
0580     if (ret) {
0581         perror("ptrace(PTRACE_GETREGSET) failed");
0582         return TEST_FAIL;
0583     }
0584 
0585     for (i = 14; i < 32; i++)
0586         regs->gpr[i] = val;
0587 
0588     ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CGPR, &iov);
0589     if (ret) {
0590         perror("ptrace(PTRACE_GETREGSET) failed");
0591         return TEST_FAIL;
0592     }
0593     return TEST_PASS;
0594 }
0595 
0596 /* VMX */
0597 int show_vmx(pid_t child, unsigned long vmx[][2])
0598 {
0599     int ret;
0600 
0601     ret = ptrace(PTRACE_GETVRREGS, child, 0, vmx);
0602     if (ret) {
0603         perror("ptrace(PTRACE_GETVRREGS) failed");
0604         return TEST_FAIL;
0605     }
0606     return TEST_PASS;
0607 }
0608 
0609 int show_vmx_ckpt(pid_t child, unsigned long vmx[][2])
0610 {
0611     unsigned long regs[34][2];
0612     struct iovec iov;
0613     int ret;
0614 
0615     iov.iov_base = (u64 *) regs;
0616     iov.iov_len = sizeof(regs);
0617     ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVMX, &iov);
0618     if (ret) {
0619         perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVMX) failed");
0620         return TEST_FAIL;
0621     }
0622     memcpy(vmx, regs, sizeof(regs));
0623     return TEST_PASS;
0624 }
0625 
0626 
0627 int write_vmx(pid_t child, unsigned long vmx[][2])
0628 {
0629     int ret;
0630 
0631     ret = ptrace(PTRACE_SETVRREGS, child, 0, vmx);
0632     if (ret) {
0633         perror("ptrace(PTRACE_SETVRREGS) failed");
0634         return TEST_FAIL;
0635     }
0636     return TEST_PASS;
0637 }
0638 
0639 int write_vmx_ckpt(pid_t child, unsigned long vmx[][2])
0640 {
0641     unsigned long regs[34][2];
0642     struct iovec iov;
0643     int ret;
0644 
0645     memcpy(regs, vmx, sizeof(regs));
0646     iov.iov_base = (u64 *) regs;
0647     iov.iov_len = sizeof(regs);
0648     ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CVMX, &iov);
0649     if (ret) {
0650         perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVMX) failed");
0651         return TEST_FAIL;
0652     }
0653     return TEST_PASS;
0654 }
0655 
0656 /* VSX */
0657 int show_vsx(pid_t child, unsigned long *vsx)
0658 {
0659     int ret;
0660 
0661     ret = ptrace(PTRACE_GETVSRREGS, child, 0, vsx);
0662     if (ret) {
0663         perror("ptrace(PTRACE_GETVSRREGS) failed");
0664         return TEST_FAIL;
0665     }
0666     return TEST_PASS;
0667 }
0668 
0669 int show_vsx_ckpt(pid_t child, unsigned long *vsx)
0670 {
0671     unsigned long regs[32];
0672     struct iovec iov;
0673     int ret;
0674 
0675     iov.iov_base = (u64 *) regs;
0676     iov.iov_len = sizeof(regs);
0677     ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVSX, &iov);
0678     if (ret) {
0679         perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVSX) failed");
0680         return TEST_FAIL;
0681     }
0682     memcpy(vsx, regs, sizeof(regs));
0683     return TEST_PASS;
0684 }
0685 
0686 int write_vsx(pid_t child, unsigned long *vsx)
0687 {
0688     int ret;
0689 
0690     ret = ptrace(PTRACE_SETVSRREGS, child, 0, vsx);
0691     if (ret) {
0692         perror("ptrace(PTRACE_SETVSRREGS) failed");
0693         return TEST_FAIL;
0694     }
0695     return TEST_PASS;
0696 }
0697 
0698 int write_vsx_ckpt(pid_t child, unsigned long *vsx)
0699 {
0700     unsigned long regs[32];
0701     struct iovec iov;
0702     int ret;
0703 
0704     memcpy(regs, vsx, sizeof(regs));
0705     iov.iov_base = (u64 *) regs;
0706     iov.iov_len = sizeof(regs);
0707     ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CVSX, &iov);
0708     if (ret) {
0709         perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVSX) failed");
0710         return TEST_FAIL;
0711     }
0712     return TEST_PASS;
0713 }
0714 
0715 /* TM SPR */
0716 int show_tm_spr(pid_t child, struct tm_spr_regs *out)
0717 {
0718     struct tm_spr_regs *regs;
0719     struct iovec iov;
0720     int ret;
0721 
0722     regs = (struct tm_spr_regs *) malloc(sizeof(struct tm_spr_regs));
0723     if (!regs) {
0724         perror("malloc() failed");
0725         return TEST_FAIL;
0726     }
0727 
0728     iov.iov_base = (u64 *) regs;
0729     iov.iov_len = sizeof(struct tm_spr_regs);
0730 
0731     ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_SPR, &iov);
0732     if (ret) {
0733         perror("ptrace(PTRACE_GETREGSET) failed");
0734         return TEST_FAIL;
0735     }
0736 
0737     if (out)
0738         memcpy(out, regs, sizeof(struct tm_spr_regs));
0739 
0740     return TEST_PASS;
0741 }
0742 
0743 
0744 
0745 /* Analyse TEXASR after TM failure */
0746 inline unsigned long get_tfiar(void)
0747 {
0748     unsigned long ret;
0749 
0750     asm volatile("mfspr %0,%1" : "=r" (ret) : "i" (SPRN_TFIAR));
0751     return ret;
0752 }
0753 
0754 void analyse_texasr(unsigned long texasr)
0755 {
0756     printf("TEXASR: %16lx\t", texasr);
0757 
0758     if (texasr & TEXASR_FP)
0759         printf("TEXASR_FP  ");
0760 
0761     if (texasr & TEXASR_DA)
0762         printf("TEXASR_DA  ");
0763 
0764     if (texasr & TEXASR_NO)
0765         printf("TEXASR_NO  ");
0766 
0767     if (texasr & TEXASR_FO)
0768         printf("TEXASR_FO  ");
0769 
0770     if (texasr & TEXASR_SIC)
0771         printf("TEXASR_SIC  ");
0772 
0773     if (texasr & TEXASR_NTC)
0774         printf("TEXASR_NTC  ");
0775 
0776     if (texasr & TEXASR_TC)
0777         printf("TEXASR_TC  ");
0778 
0779     if (texasr & TEXASR_TIC)
0780         printf("TEXASR_TIC  ");
0781 
0782     if (texasr & TEXASR_IC)
0783         printf("TEXASR_IC  ");
0784 
0785     if (texasr & TEXASR_IFC)
0786         printf("TEXASR_IFC  ");
0787 
0788     if (texasr & TEXASR_ABT)
0789         printf("TEXASR_ABT  ");
0790 
0791     if (texasr & TEXASR_SPD)
0792         printf("TEXASR_SPD  ");
0793 
0794     if (texasr & TEXASR_HV)
0795         printf("TEXASR_HV  ");
0796 
0797     if (texasr & TEXASR_PR)
0798         printf("TEXASR_PR  ");
0799 
0800     if (texasr & TEXASR_FS)
0801         printf("TEXASR_FS  ");
0802 
0803     if (texasr & TEXASR_TE)
0804         printf("TEXASR_TE  ");
0805 
0806     if (texasr & TEXASR_ROT)
0807         printf("TEXASR_ROT  ");
0808 
0809     printf("TFIAR :%lx\n", get_tfiar());
0810 }
0811 
0812 void store_gpr(unsigned long *addr);