Messages in this thread Patch in this message | | | From | wei.guo.simon@gmail ... | Subject | [PATCH v12 08/30] powerpc/ptrace: Enable support for NT_PPC_CFPR | Date | Wed, 27 Jul 2016 17:26:33 +0800 |
| |
From: Anshuman Khandual <khandual@linux.vnet.ibm.com>
This patch enables support for TM checkpointed FPR register set ELF core note NT_PPC_CFPR based ptrace requests through PTRACE_GETREGSET, PTRACE_SETREGSET calls. This is achieved through adding a register set REGSET_CFPR in powerpc corresponding to the ELF core note section added. It implements the get, set and active functions for this new register set added.
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Shuah Khan <shuahkh@osg.samsung.com> Cc: Anton Blanchard <anton@samba.org> Cc: Cyril Bur <cyrilbur@gmail.com> Cc: Anshuman Khandual <khandual@linux.vnet.ibm.com> Cc: Simon Guo <wei.guo.simon@gmail.com> Cc: Ulrich Weigand <ulrich.weigand@de.ibm.com> Cc: Michael Neuling <mikey@neuling.org> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Kees Cook <keescook@chromium.org> Cc: Rashmica Gupta <rashmicy@gmail.com> Cc: Khem Raj <raj.khem@gmail.com> Cc: Jessica Yu <jeyu@redhat.com> Cc: Jiri Kosina <jkosina@suse.cz> Cc: Miroslav Benes <mbenes@suse.cz> Cc: Suraj Jitindar Singh <sjitindarsingh@gmail.com> Cc: Chris Smart <chris@distroguy.com> Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-kernel@vger.kernel.org Cc: linux-kselftest@vger.kernel.org Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com> --- arch/powerpc/kernel/ptrace.c | 126 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+)
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index d42c79a..cd10022 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -1032,6 +1032,121 @@ static int tm_cgpr_set(struct task_struct *target, return ret; } + +/** + * tm_cfpr_active - get active number of registers in CFPR + * @target: The target task. + * @regset: The user regset structure. + * + * This function checks for the active number of available + * regisers in transaction checkpointed FPR category. + */ +static int tm_cfpr_active(struct task_struct *target, + const struct user_regset *regset) +{ + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return 0; + + return regset->n; +} + +/** + * 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. + * + * This function gets in transaction checkpointed FPR registers. + * + * When the transaction is active 'fp_state' holds the checkpointed + * values for the current transaction to fall back on if it aborts + * in between. This function gets those checkpointed FPR registers. + * The userspace interface buffer layout is as follows. + * + * struct data { + * u64 fpr[32]; + * u64 fpscr; + *}; + */ +static int tm_cfpr_get(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + void *kbuf, void __user *ubuf) +{ + u64 buf[33]; + int i; + + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return -ENODATA; + + flush_fp_to_thread(target); + flush_altivec_to_thread(target); + flush_tmregs_to_thread(target); + + /* copy to local buffer then write that out */ + for (i = 0; i < 32 ; i++) + buf[i] = target->thread.TS_FPR(i); + buf[32] = target->thread.fp_state.fpscr; + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1); +} + +/** + * tm_cfpr_set - set 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 into. + * @ubuf: User buffer to copy from. + * + * This function sets in transaction checkpointed FPR registers. + * + * When the transaction is active 'fp_state' holds the checkpointed + * FPR register values for the current transaction to fall back on + * if it aborts in between. This function sets these checkpointed + * FPR registers. The userspace interface buffer layout is as follows. + * + * struct data { + * u64 fpr[32]; + * u64 fpscr; + *}; + */ +static int tm_cfpr_set(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + u64 buf[33]; + int i; + + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return -ENODATA; + + flush_fp_to_thread(target); + flush_altivec_to_thread(target); + flush_tmregs_to_thread(target); + + /* copy to local buffer then write that out */ + i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1); + if (i) + return i; + for (i = 0; i < 32 ; i++) + target->thread.TS_FPR(i) = buf[i]; + target->thread.fp_state.fpscr = buf[32]; + return 0; +} #endif /* @@ -1051,6 +1166,7 @@ enum powerpc_regset { #endif #ifdef CONFIG_PPC_TRANSACTIONAL_MEM REGSET_TM_CGPR, /* TM checkpointed GPR registers */ + REGSET_TM_CFPR, /* TM checkpointed FPR registers */ #endif }; @@ -1092,6 +1208,11 @@ static const struct user_regset native_regsets[] = { .size = sizeof(long), .align = sizeof(long), .active = tm_cgpr_active, .get = tm_cgpr_get, .set = tm_cgpr_set }, + [REGSET_TM_CFPR] = { + .core_note_type = NT_PPC_TM_CFPR, .n = ELF_NFPREG, + .size = sizeof(double), .align = sizeof(double), + .active = tm_cfpr_active, .get = tm_cfpr_get, .set = tm_cfpr_set + }, #endif }; @@ -1324,6 +1445,11 @@ static const struct user_regset compat_regsets[] = { .active = tm_cgpr_active, .get = tm_cgpr32_get, .set = tm_cgpr32_set }, + [REGSET_TM_CFPR] = { + .core_note_type = NT_PPC_TM_CFPR, .n = ELF_NFPREG, + .size = sizeof(double), .align = sizeof(double), + .active = tm_cfpr_active, .get = tm_cfpr_get, .set = tm_cfpr_set + }, #endif }; -- 1.8.3.1
| |