Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 
0003 #include <linux/regset.h>
0004 
0005 #include <asm/switch_to.h>
0006 #include <asm/tm.h>
0007 #include <asm/asm-prototypes.h>
0008 
0009 #include "ptrace-decl.h"
0010 
0011 void flush_tmregs_to_thread(struct task_struct *tsk)
0012 {
0013     /*
0014      * If task is not current, it will have been flushed already to
0015      * it's thread_struct during __switch_to().
0016      *
0017      * A reclaim flushes ALL the state or if not in TM save TM SPRs
0018      * in the appropriate thread structures from live.
0019      */
0020 
0021     if (!cpu_has_feature(CPU_FTR_TM) || tsk != current)
0022         return;
0023 
0024     if (MSR_TM_SUSPENDED(mfmsr())) {
0025         tm_reclaim_current(TM_CAUSE_SIGNAL);
0026     } else {
0027         tm_enable();
0028         tm_save_sprs(&tsk->thread);
0029     }
0030 }
0031 
0032 static unsigned long get_user_ckpt_msr(struct task_struct *task)
0033 {
0034     return task->thread.ckpt_regs.msr | task->thread.fpexc_mode;
0035 }
0036 
0037 static int set_user_ckpt_msr(struct task_struct *task, unsigned long msr)
0038 {
0039     task->thread.ckpt_regs.msr &= ~MSR_DEBUGCHANGE;
0040     task->thread.ckpt_regs.msr |= msr & MSR_DEBUGCHANGE;
0041     return 0;
0042 }
0043 
0044 static int set_user_ckpt_trap(struct task_struct *task, unsigned long trap)
0045 {
0046     set_trap(&task->thread.ckpt_regs, trap);
0047     return 0;
0048 }
0049 
0050 /**
0051  * tm_cgpr_active - get active number of registers in CGPR
0052  * @target: The target task.
0053  * @regset: The user regset structure.
0054  *
0055  * This function checks for the active number of available
0056  * regisers in transaction checkpointed GPR category.
0057  */
0058 int tm_cgpr_active(struct task_struct *target, const struct user_regset *regset)
0059 {
0060     if (!cpu_has_feature(CPU_FTR_TM))
0061         return -ENODEV;
0062 
0063     if (!MSR_TM_ACTIVE(target->thread.regs->msr))
0064         return 0;
0065 
0066     return regset->n;
0067 }
0068 
0069 /**
0070  * tm_cgpr_get - get CGPR registers
0071  * @target: The target task.
0072  * @regset: The user regset structure.
0073  * @to:     Destination of copy.
0074  *
0075  * This function gets transaction checkpointed GPR registers.
0076  *
0077  * When the transaction is active, 'ckpt_regs' holds all the checkpointed
0078  * GPR register values for the current transaction to fall back on if it
0079  * aborts in between. This function gets those checkpointed GPR registers.
0080  * The userspace interface buffer layout is as follows.
0081  *
0082  * struct data {
0083  *  struct pt_regs ckpt_regs;
0084  * };
0085  */
0086 int tm_cgpr_get(struct task_struct *target, const struct user_regset *regset,
0087         struct membuf to)
0088 {
0089     struct membuf to_msr = membuf_at(&to, offsetof(struct pt_regs, msr));
0090 #ifdef CONFIG_PPC64
0091     struct membuf to_softe = membuf_at(&to, offsetof(struct pt_regs, softe));
0092 #endif
0093 
0094     if (!cpu_has_feature(CPU_FTR_TM))
0095         return -ENODEV;
0096 
0097     if (!MSR_TM_ACTIVE(target->thread.regs->msr))
0098         return -ENODATA;
0099 
0100     flush_tmregs_to_thread(target);
0101     flush_fp_to_thread(target);
0102     flush_altivec_to_thread(target);
0103 
0104     membuf_write(&to, &target->thread.ckpt_regs, sizeof(struct user_pt_regs));
0105 
0106     membuf_store(&to_msr, get_user_ckpt_msr(target));
0107 #ifdef CONFIG_PPC64
0108     membuf_store(&to_softe, 0x1ul);
0109 #endif
0110     return membuf_zero(&to, ELF_NGREG * sizeof(unsigned long) -
0111             sizeof(struct user_pt_regs));
0112 }
0113 
0114 /*
0115  * tm_cgpr_set - set the CGPR registers
0116  * @target: The target task.
0117  * @regset: The user regset structure.
0118  * @pos:    The buffer position.
0119  * @count:  Number of bytes to copy.
0120  * @kbuf:   Kernel buffer to copy into.
0121  * @ubuf:   User buffer to copy from.
0122  *
0123  * This function sets in transaction checkpointed GPR registers.
0124  *
0125  * When the transaction is active, 'ckpt_regs' holds the checkpointed
0126  * GPR register values for the current transaction to fall back on if it
0127  * aborts in between. This function sets those checkpointed GPR registers.
0128  * The userspace interface buffer layout is as follows.
0129  *
0130  * struct data {
0131  *  struct pt_regs ckpt_regs;
0132  * };
0133  */
0134 int tm_cgpr_set(struct task_struct *target, const struct user_regset *regset,
0135         unsigned int pos, unsigned int count,
0136         const void *kbuf, const void __user *ubuf)
0137 {
0138     unsigned long reg;
0139     int ret;
0140 
0141     if (!cpu_has_feature(CPU_FTR_TM))
0142         return -ENODEV;
0143 
0144     if (!MSR_TM_ACTIVE(target->thread.regs->msr))
0145         return -ENODATA;
0146 
0147     flush_tmregs_to_thread(target);
0148     flush_fp_to_thread(target);
0149     flush_altivec_to_thread(target);
0150 
0151     ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
0152                  &target->thread.ckpt_regs,
0153                  0, PT_MSR * sizeof(reg));
0154 
0155     if (!ret && count > 0) {
0156         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &reg,
0157                      PT_MSR * sizeof(reg),
0158                      (PT_MSR + 1) * sizeof(reg));
0159         if (!ret)
0160             ret = set_user_ckpt_msr(target, reg);
0161     }
0162 
0163     BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) !=
0164              offsetof(struct pt_regs, msr) + sizeof(long));
0165 
0166     if (!ret)
0167         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
0168                      &target->thread.ckpt_regs.orig_gpr3,
0169                      PT_ORIG_R3 * sizeof(reg),
0170                      (PT_MAX_PUT_REG + 1) * sizeof(reg));
0171 
0172     if (PT_MAX_PUT_REG + 1 < PT_TRAP && !ret)
0173         ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
0174                         (PT_MAX_PUT_REG + 1) * sizeof(reg),
0175                         PT_TRAP * sizeof(reg));
0176 
0177     if (!ret && count > 0) {
0178         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &reg,
0179                      PT_TRAP * sizeof(reg),
0180                      (PT_TRAP + 1) * sizeof(reg));
0181         if (!ret)
0182             ret = set_user_ckpt_trap(target, reg);
0183     }
0184 
0185     if (!ret)
0186         ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
0187                         (PT_TRAP + 1) * sizeof(reg), -1);
0188 
0189     return ret;
0190 }
0191 
0192 /**
0193  * tm_cfpr_active - get active number of registers in CFPR
0194  * @target: The target task.
0195  * @regset: The user regset structure.
0196  *
0197  * This function checks for the active number of available
0198  * regisers in transaction checkpointed FPR category.
0199  */
0200 int tm_cfpr_active(struct task_struct *target, const struct user_regset *regset)
0201 {
0202     if (!cpu_has_feature(CPU_FTR_TM))
0203         return -ENODEV;
0204 
0205     if (!MSR_TM_ACTIVE(target->thread.regs->msr))
0206         return 0;
0207 
0208     return regset->n;
0209 }
0210 
0211 /**
0212  * tm_cfpr_get - get CFPR registers
0213  * @target: The target task.
0214  * @regset: The user regset structure.
0215  * @to:     Destination of copy.
0216  *
0217  * This function gets in transaction checkpointed FPR registers.
0218  *
0219  * When the transaction is active 'ckfp_state' holds the checkpointed
0220  * values for the current transaction to fall back on if it aborts
0221  * in between. This function gets those checkpointed FPR registers.
0222  * The userspace interface buffer layout is as follows.
0223  *
0224  * struct data {
0225  *  u64 fpr[32];
0226  *  u64 fpscr;
0227  *};
0228  */
0229 int tm_cfpr_get(struct task_struct *target, const struct user_regset *regset,
0230         struct membuf to)
0231 {
0232     u64 buf[33];
0233     int i;
0234 
0235     if (!cpu_has_feature(CPU_FTR_TM))
0236         return -ENODEV;
0237 
0238     if (!MSR_TM_ACTIVE(target->thread.regs->msr))
0239         return -ENODATA;
0240 
0241     flush_tmregs_to_thread(target);
0242     flush_fp_to_thread(target);
0243     flush_altivec_to_thread(target);
0244 
0245     /* copy to local buffer then write that out */
0246     for (i = 0; i < 32 ; i++)
0247         buf[i] = target->thread.TS_CKFPR(i);
0248     buf[32] = target->thread.ckfp_state.fpscr;
0249     return membuf_write(&to, buf, sizeof(buf));
0250 }
0251 
0252 /**
0253  * tm_cfpr_set - set CFPR registers
0254  * @target: The target task.
0255  * @regset: The user regset structure.
0256  * @pos:    The buffer position.
0257  * @count:  Number of bytes to copy.
0258  * @kbuf:   Kernel buffer to copy into.
0259  * @ubuf:   User buffer to copy from.
0260  *
0261  * This function sets in transaction checkpointed FPR registers.
0262  *
0263  * When the transaction is active 'ckfp_state' holds the checkpointed
0264  * FPR register values for the current transaction to fall back on
0265  * if it aborts in between. This function sets these checkpointed
0266  * FPR registers. The userspace interface buffer layout is as follows.
0267  *
0268  * struct data {
0269  *  u64 fpr[32];
0270  *  u64 fpscr;
0271  *};
0272  */
0273 int tm_cfpr_set(struct task_struct *target, const struct user_regset *regset,
0274         unsigned int pos, unsigned int count,
0275         const void *kbuf, const void __user *ubuf)
0276 {
0277     u64 buf[33];
0278     int i;
0279 
0280     if (!cpu_has_feature(CPU_FTR_TM))
0281         return -ENODEV;
0282 
0283     if (!MSR_TM_ACTIVE(target->thread.regs->msr))
0284         return -ENODATA;
0285 
0286     flush_tmregs_to_thread(target);
0287     flush_fp_to_thread(target);
0288     flush_altivec_to_thread(target);
0289 
0290     for (i = 0; i < 32; i++)
0291         buf[i] = target->thread.TS_CKFPR(i);
0292     buf[32] = target->thread.ckfp_state.fpscr;
0293 
0294     /* copy to local buffer then write that out */
0295     i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
0296     if (i)
0297         return i;
0298     for (i = 0; i < 32 ; i++)
0299         target->thread.TS_CKFPR(i) = buf[i];
0300     target->thread.ckfp_state.fpscr = buf[32];
0301     return 0;
0302 }
0303 
0304 /**
0305  * tm_cvmx_active - get active number of registers in CVMX
0306  * @target: The target task.
0307  * @regset: The user regset structure.
0308  *
0309  * This function checks for the active number of available
0310  * regisers in checkpointed VMX category.
0311  */
0312 int tm_cvmx_active(struct task_struct *target, const struct user_regset *regset)
0313 {
0314     if (!cpu_has_feature(CPU_FTR_TM))
0315         return -ENODEV;
0316 
0317     if (!MSR_TM_ACTIVE(target->thread.regs->msr))
0318         return 0;
0319 
0320     return regset->n;
0321 }
0322 
0323 /**
0324  * tm_cvmx_get - get CMVX registers
0325  * @target: The target task.
0326  * @regset: The user regset structure.
0327  * @to:     Destination of copy.
0328  *
0329  * This function gets in transaction checkpointed VMX registers.
0330  *
0331  * When the transaction is active 'ckvr_state' and 'ckvrsave' hold
0332  * the checkpointed values for the current transaction to fall
0333  * back on if it aborts in between. The userspace interface buffer
0334  * layout is as follows.
0335  *
0336  * struct data {
0337  *  vector128   vr[32];
0338  *  vector128   vscr;
0339  *  vector128   vrsave;
0340  *};
0341  */
0342 int tm_cvmx_get(struct task_struct *target, const struct user_regset *regset,
0343         struct membuf to)
0344 {
0345     union {
0346         elf_vrreg_t reg;
0347         u32 word;
0348     } vrsave;
0349     BUILD_BUG_ON(TVSO(vscr) != TVSO(vr[32]));
0350 
0351     if (!cpu_has_feature(CPU_FTR_TM))
0352         return -ENODEV;
0353 
0354     if (!MSR_TM_ACTIVE(target->thread.regs->msr))
0355         return -ENODATA;
0356 
0357     /* Flush the state */
0358     flush_tmregs_to_thread(target);
0359     flush_fp_to_thread(target);
0360     flush_altivec_to_thread(target);
0361 
0362     membuf_write(&to, &target->thread.ckvr_state, 33 * sizeof(vector128));
0363     /*
0364      * Copy out only the low-order word of vrsave.
0365      */
0366     memset(&vrsave, 0, sizeof(vrsave));
0367     vrsave.word = target->thread.ckvrsave;
0368     return membuf_write(&to, &vrsave, sizeof(vrsave));
0369 }
0370 
0371 /**
0372  * tm_cvmx_set - set CMVX registers
0373  * @target: The target task.
0374  * @regset: The user regset structure.
0375  * @pos:    The buffer position.
0376  * @count:  Number of bytes to copy.
0377  * @kbuf:   Kernel buffer to copy into.
0378  * @ubuf:   User buffer to copy from.
0379  *
0380  * This function sets in transaction checkpointed VMX registers.
0381  *
0382  * When the transaction is active 'ckvr_state' and 'ckvrsave' hold
0383  * the checkpointed values for the current transaction to fall
0384  * back on if it aborts in between. The userspace interface buffer
0385  * layout is as follows.
0386  *
0387  * struct data {
0388  *  vector128   vr[32];
0389  *  vector128   vscr;
0390  *  vector128   vrsave;
0391  *};
0392  */
0393 int tm_cvmx_set(struct task_struct *target, const struct user_regset *regset,
0394         unsigned int pos, unsigned int count,
0395         const void *kbuf, const void __user *ubuf)
0396 {
0397     int ret;
0398 
0399     BUILD_BUG_ON(TVSO(vscr) != TVSO(vr[32]));
0400 
0401     if (!cpu_has_feature(CPU_FTR_TM))
0402         return -ENODEV;
0403 
0404     if (!MSR_TM_ACTIVE(target->thread.regs->msr))
0405         return -ENODATA;
0406 
0407     flush_tmregs_to_thread(target);
0408     flush_fp_to_thread(target);
0409     flush_altivec_to_thread(target);
0410 
0411     ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &target->thread.ckvr_state,
0412                  0, 33 * sizeof(vector128));
0413     if (!ret && count > 0) {
0414         /*
0415          * We use only the low-order word of vrsave.
0416          */
0417         union {
0418             elf_vrreg_t reg;
0419             u32 word;
0420         } vrsave;
0421         memset(&vrsave, 0, sizeof(vrsave));
0422         vrsave.word = target->thread.ckvrsave;
0423         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
0424                      33 * sizeof(vector128), -1);
0425         if (!ret)
0426             target->thread.ckvrsave = vrsave.word;
0427     }
0428 
0429     return ret;
0430 }
0431 
0432 /**
0433  * tm_cvsx_active - get active number of registers in CVSX
0434  * @target: The target task.
0435  * @regset: The user regset structure.
0436  *
0437  * This function checks for the active number of available
0438  * regisers in transaction checkpointed VSX category.
0439  */
0440 int tm_cvsx_active(struct task_struct *target, const struct user_regset *regset)
0441 {
0442     if (!cpu_has_feature(CPU_FTR_TM))
0443         return -ENODEV;
0444 
0445     if (!MSR_TM_ACTIVE(target->thread.regs->msr))
0446         return 0;
0447 
0448     flush_vsx_to_thread(target);
0449     return target->thread.used_vsr ? regset->n : 0;
0450 }
0451 
0452 /**
0453  * tm_cvsx_get - get CVSX registers
0454  * @target: The target task.
0455  * @regset: The user regset structure.
0456  * @to:     Destination of copy.
0457  *
0458  * This function gets in transaction checkpointed VSX registers.
0459  *
0460  * When the transaction is active 'ckfp_state' holds the checkpointed
0461  * values for the current transaction to fall back on if it aborts
0462  * in between. This function gets those checkpointed VSX registers.
0463  * The userspace interface buffer layout is as follows.
0464  *
0465  * struct data {
0466  *  u64 vsx[32];
0467  *};
0468  */
0469 int tm_cvsx_get(struct task_struct *target, const struct user_regset *regset,
0470         struct membuf to)
0471 {
0472     u64 buf[32];
0473     int i;
0474 
0475     if (!cpu_has_feature(CPU_FTR_TM))
0476         return -ENODEV;
0477 
0478     if (!MSR_TM_ACTIVE(target->thread.regs->msr))
0479         return -ENODATA;
0480 
0481     /* Flush the state */
0482     flush_tmregs_to_thread(target);
0483     flush_fp_to_thread(target);
0484     flush_altivec_to_thread(target);
0485     flush_vsx_to_thread(target);
0486 
0487     for (i = 0; i < 32 ; i++)
0488         buf[i] = target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET];
0489     return membuf_write(&to, buf, 32 * sizeof(double));
0490 }
0491 
0492 /**
0493  * tm_cvsx_set - set CFPR registers
0494  * @target: The target task.
0495  * @regset: The user regset structure.
0496  * @pos:    The buffer position.
0497  * @count:  Number of bytes to copy.
0498  * @kbuf:   Kernel buffer to copy into.
0499  * @ubuf:   User buffer to copy from.
0500  *
0501  * This function sets in transaction checkpointed VSX registers.
0502  *
0503  * When the transaction is active 'ckfp_state' holds the checkpointed
0504  * VSX register values for the current transaction to fall back on
0505  * if it aborts in between. This function sets these checkpointed
0506  * FPR registers. The userspace interface buffer layout is as follows.
0507  *
0508  * struct data {
0509  *  u64 vsx[32];
0510  *};
0511  */
0512 int tm_cvsx_set(struct task_struct *target, const struct user_regset *regset,
0513         unsigned int pos, unsigned int count,
0514         const void *kbuf, const void __user *ubuf)
0515 {
0516     u64 buf[32];
0517     int ret, i;
0518 
0519     if (!cpu_has_feature(CPU_FTR_TM))
0520         return -ENODEV;
0521 
0522     if (!MSR_TM_ACTIVE(target->thread.regs->msr))
0523         return -ENODATA;
0524 
0525     /* Flush the state */
0526     flush_tmregs_to_thread(target);
0527     flush_fp_to_thread(target);
0528     flush_altivec_to_thread(target);
0529     flush_vsx_to_thread(target);
0530 
0531     for (i = 0; i < 32 ; i++)
0532         buf[i] = target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET];
0533 
0534     ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
0535                  buf, 0, 32 * sizeof(double));
0536     if (!ret)
0537         for (i = 0; i < 32 ; i++)
0538             target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
0539 
0540     return ret;
0541 }
0542 
0543 /**
0544  * tm_spr_active - get active number of registers in TM SPR
0545  * @target: The target task.
0546  * @regset: The user regset structure.
0547  *
0548  * This function checks the active number of available
0549  * regisers in the transactional memory SPR category.
0550  */
0551 int tm_spr_active(struct task_struct *target, const struct user_regset *regset)
0552 {
0553     if (!cpu_has_feature(CPU_FTR_TM))
0554         return -ENODEV;
0555 
0556     return regset->n;
0557 }
0558 
0559 /**
0560  * tm_spr_get - get the TM related SPR registers
0561  * @target: The target task.
0562  * @regset: The user regset structure.
0563  * @to:     Destination of copy.
0564  *
0565  * This function gets transactional memory related SPR registers.
0566  * The userspace interface buffer layout is as follows.
0567  *
0568  * struct {
0569  *  u64     tm_tfhar;
0570  *  u64     tm_texasr;
0571  *  u64     tm_tfiar;
0572  * };
0573  */
0574 int tm_spr_get(struct task_struct *target, const struct user_regset *regset,
0575            struct membuf to)
0576 {
0577     /* Build tests */
0578     BUILD_BUG_ON(TSO(tm_tfhar) + sizeof(u64) != TSO(tm_texasr));
0579     BUILD_BUG_ON(TSO(tm_texasr) + sizeof(u64) != TSO(tm_tfiar));
0580     BUILD_BUG_ON(TSO(tm_tfiar) + sizeof(u64) != TSO(ckpt_regs));
0581 
0582     if (!cpu_has_feature(CPU_FTR_TM))
0583         return -ENODEV;
0584 
0585     /* Flush the states */
0586     flush_tmregs_to_thread(target);
0587     flush_fp_to_thread(target);
0588     flush_altivec_to_thread(target);
0589 
0590     /* TFHAR register */
0591     membuf_write(&to, &target->thread.tm_tfhar, sizeof(u64));
0592     /* TEXASR register */
0593     membuf_write(&to, &target->thread.tm_texasr, sizeof(u64));
0594     /* TFIAR register */
0595     return membuf_write(&to, &target->thread.tm_tfiar, sizeof(u64));
0596 }
0597 
0598 /**
0599  * tm_spr_set - set the TM related SPR registers
0600  * @target: The target task.
0601  * @regset: The user regset structure.
0602  * @pos:    The buffer position.
0603  * @count:  Number of bytes to copy.
0604  * @kbuf:   Kernel buffer to copy into.
0605  * @ubuf:   User buffer to copy from.
0606  *
0607  * This function sets transactional memory related SPR registers.
0608  * The userspace interface buffer layout is as follows.
0609  *
0610  * struct {
0611  *  u64     tm_tfhar;
0612  *  u64     tm_texasr;
0613  *  u64     tm_tfiar;
0614  * };
0615  */
0616 int tm_spr_set(struct task_struct *target, const struct user_regset *regset,
0617            unsigned int pos, unsigned int count,
0618            const void *kbuf, const void __user *ubuf)
0619 {
0620     int ret;
0621 
0622     /* Build tests */
0623     BUILD_BUG_ON(TSO(tm_tfhar) + sizeof(u64) != TSO(tm_texasr));
0624     BUILD_BUG_ON(TSO(tm_texasr) + sizeof(u64) != TSO(tm_tfiar));
0625     BUILD_BUG_ON(TSO(tm_tfiar) + sizeof(u64) != TSO(ckpt_regs));
0626 
0627     if (!cpu_has_feature(CPU_FTR_TM))
0628         return -ENODEV;
0629 
0630     /* Flush the states */
0631     flush_tmregs_to_thread(target);
0632     flush_fp_to_thread(target);
0633     flush_altivec_to_thread(target);
0634 
0635     /* TFHAR register */
0636     ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
0637                  &target->thread.tm_tfhar, 0, sizeof(u64));
0638 
0639     /* TEXASR register */
0640     if (!ret)
0641         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
0642                      &target->thread.tm_texasr, sizeof(u64),
0643                      2 * sizeof(u64));
0644 
0645     /* TFIAR register */
0646     if (!ret)
0647         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
0648                      &target->thread.tm_tfiar,
0649                      2 * sizeof(u64), 3 * sizeof(u64));
0650     return ret;
0651 }
0652 
0653 int tm_tar_active(struct task_struct *target, const struct user_regset *regset)
0654 {
0655     if (!cpu_has_feature(CPU_FTR_TM))
0656         return -ENODEV;
0657 
0658     if (MSR_TM_ACTIVE(target->thread.regs->msr))
0659         return regset->n;
0660 
0661     return 0;
0662 }
0663 
0664 int tm_tar_get(struct task_struct *target, const struct user_regset *regset,
0665            struct membuf to)
0666 {
0667     if (!cpu_has_feature(CPU_FTR_TM))
0668         return -ENODEV;
0669 
0670     if (!MSR_TM_ACTIVE(target->thread.regs->msr))
0671         return -ENODATA;
0672 
0673     return membuf_write(&to, &target->thread.tm_tar, sizeof(u64));
0674 }
0675 
0676 int tm_tar_set(struct task_struct *target, const struct user_regset *regset,
0677            unsigned int pos, unsigned int count,
0678            const void *kbuf, const void __user *ubuf)
0679 {
0680     int ret;
0681 
0682     if (!cpu_has_feature(CPU_FTR_TM))
0683         return -ENODEV;
0684 
0685     if (!MSR_TM_ACTIVE(target->thread.regs->msr))
0686         return -ENODATA;
0687 
0688     ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
0689                  &target->thread.tm_tar, 0, sizeof(u64));
0690     return ret;
0691 }
0692 
0693 int tm_ppr_active(struct task_struct *target, const struct user_regset *regset)
0694 {
0695     if (!cpu_has_feature(CPU_FTR_TM))
0696         return -ENODEV;
0697 
0698     if (MSR_TM_ACTIVE(target->thread.regs->msr))
0699         return regset->n;
0700 
0701     return 0;
0702 }
0703 
0704 
0705 int tm_ppr_get(struct task_struct *target, const struct user_regset *regset,
0706            struct membuf to)
0707 {
0708     if (!cpu_has_feature(CPU_FTR_TM))
0709         return -ENODEV;
0710 
0711     if (!MSR_TM_ACTIVE(target->thread.regs->msr))
0712         return -ENODATA;
0713 
0714     return membuf_write(&to, &target->thread.tm_ppr, sizeof(u64));
0715 }
0716 
0717 int tm_ppr_set(struct task_struct *target, const struct user_regset *regset,
0718            unsigned int pos, unsigned int count,
0719            const void *kbuf, const void __user *ubuf)
0720 {
0721     int ret;
0722 
0723     if (!cpu_has_feature(CPU_FTR_TM))
0724         return -ENODEV;
0725 
0726     if (!MSR_TM_ACTIVE(target->thread.regs->msr))
0727         return -ENODATA;
0728 
0729     ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
0730                  &target->thread.tm_ppr, 0, sizeof(u64));
0731     return ret;
0732 }
0733 
0734 int tm_dscr_active(struct task_struct *target, const struct user_regset *regset)
0735 {
0736     if (!cpu_has_feature(CPU_FTR_TM))
0737         return -ENODEV;
0738 
0739     if (MSR_TM_ACTIVE(target->thread.regs->msr))
0740         return regset->n;
0741 
0742     return 0;
0743 }
0744 
0745 int tm_dscr_get(struct task_struct *target, const struct user_regset *regset,
0746         struct membuf to)
0747 {
0748     if (!cpu_has_feature(CPU_FTR_TM))
0749         return -ENODEV;
0750 
0751     if (!MSR_TM_ACTIVE(target->thread.regs->msr))
0752         return -ENODATA;
0753 
0754     return membuf_write(&to, &target->thread.tm_dscr, sizeof(u64));
0755 }
0756 
0757 int tm_dscr_set(struct task_struct *target, const struct user_regset *regset,
0758         unsigned int pos, unsigned int count,
0759         const void *kbuf, const void __user *ubuf)
0760 {
0761     int ret;
0762 
0763     if (!cpu_has_feature(CPU_FTR_TM))
0764         return -ENODEV;
0765 
0766     if (!MSR_TM_ACTIVE(target->thread.regs->msr))
0767         return -ENODATA;
0768 
0769     ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
0770                  &target->thread.tm_dscr, 0, sizeof(u64));
0771     return ret;
0772 }
0773 
0774 int tm_cgpr32_get(struct task_struct *target, const struct user_regset *regset,
0775           struct membuf to)
0776 {
0777     gpr32_get_common(target, regset, to,
0778                 &target->thread.ckpt_regs.gpr[0]);
0779     return membuf_zero(&to, ELF_NGREG * sizeof(u32));
0780 }
0781 
0782 int tm_cgpr32_set(struct task_struct *target, const struct user_regset *regset,
0783           unsigned int pos, unsigned int count,
0784           const void *kbuf, const void __user *ubuf)
0785 {
0786     return gpr32_set_common(target, regset, pos, count, kbuf, ubuf,
0787                 &target->thread.ckpt_regs.gpr[0]);
0788 }