diff options
Diffstat (limited to 'arch/powerpc/kernel/ptrace/ptrace-tm.c')
-rw-r--r-- | arch/powerpc/kernel/ptrace/ptrace-tm.c | 152 |
1 files changed, 44 insertions, 108 deletions
diff --git a/arch/powerpc/kernel/ptrace/ptrace-tm.c b/arch/powerpc/kernel/ptrace/ptrace-tm.c index 32d62c606681..54f2d076206f 100644 --- a/arch/powerpc/kernel/ptrace/ptrace-tm.c +++ b/arch/powerpc/kernel/ptrace/ptrace-tm.c @@ -70,10 +70,7 @@ int tm_cgpr_active(struct task_struct *target, const struct user_regset *regset) * tm_cgpr_get - get CGPR registers * @target: The target task. * @regset: The user regset structure. - * @pos: The buffer position. - * @count: Number of bytes to copy. - * @kbuf: Kernel buffer to copy from. - * @ubuf: User buffer to copy into. + * @to: Destination of copy. * * This function gets transaction checkpointed GPR registers. * @@ -87,10 +84,8 @@ int tm_cgpr_active(struct task_struct *target, const struct user_regset *regset) * }; */ int tm_cgpr_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) + struct membuf to) { - int ret; - if (!cpu_has_feature(CPU_FTR_TM)) return -ENODEV; @@ -101,31 +96,18 @@ int tm_cgpr_get(struct task_struct *target, const struct user_regset *regset, flush_fp_to_thread(target); flush_altivec_to_thread(target); - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.ckpt_regs, - 0, offsetof(struct pt_regs, msr)); - if (!ret) { - unsigned long msr = get_user_ckpt_msr(target); - - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &msr, - offsetof(struct pt_regs, msr), - offsetof(struct pt_regs, msr) + - sizeof(msr)); - } + membuf_write(&to, &target->thread.ckpt_regs, + offsetof(struct pt_regs, msr)); + membuf_store(&to, get_user_ckpt_msr(target)); BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) != offsetof(struct pt_regs, msr) + sizeof(long)); - if (!ret) - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.ckpt_regs.orig_gpr3, - offsetof(struct pt_regs, orig_gpr3), - sizeof(struct user_pt_regs)); - if (!ret) - ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, - sizeof(struct user_pt_regs), -1); - - return ret; + membuf_write(&to, &target->thread.ckpt_regs.orig_gpr3, + sizeof(struct user_pt_regs) - + offsetof(struct pt_regs, orig_gpr3)); + return membuf_zero(&to, ELF_NGREG * sizeof(unsigned long) - + sizeof(struct user_pt_regs)); } /* @@ -229,10 +211,7 @@ int tm_cfpr_active(struct task_struct *target, const struct user_regset *regset) * tm_cfpr_get - get CFPR registers * @target: The target task. * @regset: The user regset structure. - * @pos: The buffer position. - * @count: Number of bytes to copy. - * @kbuf: Kernel buffer to copy from. - * @ubuf: User buffer to copy into. + * @to: Destination of copy. * * This function gets in transaction checkpointed FPR registers. * @@ -247,7 +226,7 @@ int tm_cfpr_active(struct task_struct *target, const struct user_regset *regset) *}; */ int tm_cfpr_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) + struct membuf to) { u64 buf[33]; int i; @@ -266,7 +245,7 @@ int tm_cfpr_get(struct task_struct *target, const struct user_regset *regset, for (i = 0; i < 32 ; i++) buf[i] = target->thread.TS_CKFPR(i); buf[32] = target->thread.ckfp_state.fpscr; - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1); + return membuf_write(&to, buf, sizeof(buf)); } /** @@ -344,10 +323,7 @@ int tm_cvmx_active(struct task_struct *target, const struct user_regset *regset) * tm_cvmx_get - get CMVX registers * @target: The target task. * @regset: The user regset structure. - * @pos: The buffer position. - * @count: Number of bytes to copy. - * @kbuf: Kernel buffer to copy from. - * @ubuf: User buffer to copy into. + * @to: Destination of copy. * * This function gets in transaction checkpointed VMX registers. * @@ -363,10 +339,12 @@ int tm_cvmx_active(struct task_struct *target, const struct user_regset *regset) *}; */ int tm_cvmx_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) + struct membuf to) { - int ret; - + union { + elf_vrreg_t reg; + u32 word; + } vrsave; BUILD_BUG_ON(TVSO(vscr) != TVSO(vr[32])); if (!cpu_has_feature(CPU_FTR_TM)) @@ -380,23 +358,13 @@ int tm_cvmx_get(struct task_struct *target, const struct user_regset *regset, flush_fp_to_thread(target); flush_altivec_to_thread(target); - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &target->thread.ckvr_state, - 0, 33 * sizeof(vector128)); - if (!ret) { - /* - * Copy out only the low-order word of vrsave. - */ - union { - elf_vrreg_t reg; - u32 word; - } vrsave; - memset(&vrsave, 0, sizeof(vrsave)); - vrsave.word = target->thread.ckvrsave; - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave, - 33 * sizeof(vector128), -1); - } - - return ret; + membuf_write(&to, &target->thread.ckvr_state, 33 * sizeof(vector128)); + /* + * Copy out only the low-order word of vrsave. + */ + memset(&vrsave, 0, sizeof(vrsave)); + vrsave.word = target->thread.ckvrsave; + return membuf_write(&to, &vrsave, sizeof(vrsave)); } /** @@ -484,10 +452,7 @@ int tm_cvsx_active(struct task_struct *target, const struct user_regset *regset) * tm_cvsx_get - get CVSX registers * @target: The target task. * @regset: The user regset structure. - * @pos: The buffer position. - * @count: Number of bytes to copy. - * @kbuf: Kernel buffer to copy from. - * @ubuf: User buffer to copy into. + * @to: Destination of copy. * * This function gets in transaction checkpointed VSX registers. * @@ -501,10 +466,10 @@ int tm_cvsx_active(struct task_struct *target, const struct user_regset *regset) *}; */ int tm_cvsx_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) + struct membuf to) { u64 buf[32]; - int ret, i; + int i; if (!cpu_has_feature(CPU_FTR_TM)) return -ENODEV; @@ -520,10 +485,7 @@ int tm_cvsx_get(struct task_struct *target, const struct user_regset *regset, for (i = 0; i < 32 ; i++) buf[i] = target->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET]; - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - buf, 0, 32 * sizeof(double)); - - return ret; + return membuf_write(&to, buf, 32 * sizeof(double)); } /** @@ -597,10 +559,7 @@ int tm_spr_active(struct task_struct *target, const struct user_regset *regset) * tm_spr_get - get the TM related SPR registers * @target: The target task. * @regset: The user regset structure. - * @pos: The buffer position. - * @count: Number of bytes to copy. - * @kbuf: Kernel buffer to copy from. - * @ubuf: User buffer to copy into. + * @to: Destination of copy. * * This function gets transactional memory related SPR registers. * The userspace interface buffer layout is as follows. @@ -612,10 +571,8 @@ int tm_spr_active(struct task_struct *target, const struct user_regset *regset) * }; */ int tm_spr_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) + struct membuf to) { - int ret; - /* Build tests */ BUILD_BUG_ON(TSO(tm_tfhar) + sizeof(u64) != TSO(tm_texasr)); BUILD_BUG_ON(TSO(tm_texasr) + sizeof(u64) != TSO(tm_tfiar)); @@ -630,21 +587,11 @@ int tm_spr_get(struct task_struct *target, const struct user_regset *regset, flush_altivec_to_thread(target); /* TFHAR register */ - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.tm_tfhar, 0, sizeof(u64)); - + membuf_write(&to, &target->thread.tm_tfhar, sizeof(u64)); /* TEXASR register */ - if (!ret) - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.tm_texasr, sizeof(u64), - 2 * sizeof(u64)); - + membuf_write(&to, &target->thread.tm_texasr, sizeof(u64)); /* TFIAR register */ - if (!ret) - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.tm_tfiar, - 2 * sizeof(u64), 3 * sizeof(u64)); - return ret; + return membuf_write(&to, &target->thread.tm_tfiar, sizeof(u64)); } /** @@ -714,19 +661,15 @@ int tm_tar_active(struct task_struct *target, const struct user_regset *regset) } int tm_tar_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) + struct membuf to) { - int ret; - if (!cpu_has_feature(CPU_FTR_TM)) return -ENODEV; if (!MSR_TM_ACTIVE(target->thread.regs->msr)) return -ENODATA; - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.tm_tar, 0, sizeof(u64)); - return ret; + return membuf_write(&to, &target->thread.tm_tar, sizeof(u64)); } int tm_tar_set(struct task_struct *target, const struct user_regset *regset, @@ -759,19 +702,15 @@ int tm_ppr_active(struct task_struct *target, const struct user_regset *regset) int tm_ppr_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) + struct membuf to) { - int ret; - if (!cpu_has_feature(CPU_FTR_TM)) return -ENODEV; if (!MSR_TM_ACTIVE(target->thread.regs->msr)) return -ENODATA; - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.tm_ppr, 0, sizeof(u64)); - return ret; + return membuf_write(&to, &target->thread.tm_ppr, sizeof(u64)); } int tm_ppr_set(struct task_struct *target, const struct user_regset *regset, @@ -803,19 +742,15 @@ int tm_dscr_active(struct task_struct *target, const struct user_regset *regset) } int tm_dscr_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) + struct membuf to) { - int ret; - if (!cpu_has_feature(CPU_FTR_TM)) return -ENODEV; if (!MSR_TM_ACTIVE(target->thread.regs->msr)) return -ENODATA; - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.tm_dscr, 0, sizeof(u64)); - return ret; + return membuf_write(&to, &target->thread.tm_dscr, sizeof(u64)); } int tm_dscr_set(struct task_struct *target, const struct user_regset *regset, @@ -836,10 +771,11 @@ int tm_dscr_set(struct task_struct *target, const struct user_regset *regset, } int tm_cgpr32_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) + struct membuf to) { - return gpr32_get_common(target, regset, pos, count, kbuf, ubuf, + gpr32_get_common(target, regset, to, &target->thread.ckpt_regs.gpr[0]); + return membuf_zero(&to, ELF_NGREG * sizeof(u32)); } int tm_cgpr32_set(struct task_struct *target, const struct user_regset *regset, |