From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755337AbcG0J2Y (ORCPT ); Wed, 27 Jul 2016 05:28:24 -0400 Received: from mail-pf0-f196.google.com ([209.85.192.196]:33009 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754485AbcG0J2T (ORCPT ); Wed, 27 Jul 2016 05:28:19 -0400 From: wei.guo.simon@gmail.com To: Michael Ellerman Cc: Anshuman Khandual , Benjamin Herrenschmidt , Paul Mackerras , Shuah Khan , Anton Blanchard , Cyril Bur , Simon Guo , Ulrich Weigand , Michael Neuling , Andrew Morton , Kees Cook , Rashmica Gupta , Khem Raj , Jessica Yu , Jiri Kosina , Miroslav Benes , Suraj Jitindar Singh , Chris Smart , linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH v12 10/30] powerpc/ptrace: Enable support for NT_PPC_CVSX Date: Wed, 27 Jul 2016 17:26:35 +0800 Message-Id: <1469611615-2935-11-git-send-email-wei.guo.simon@gmail.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1469611615-2935-1-git-send-email-wei.guo.simon@gmail.com> References: <1469611615-2935-1-git-send-email-wei.guo.simon@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Anshuman Khandual This patch enables support for TM checkpointed VSX register set ELF core note NT_PPC_CVSX based ptrace requests through PTRACE_GETREGSET, PTRACE_SETREGSET calls. This is achieved through adding a register set REGSET_CVSX 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 Cc: Paul Mackerras Cc: Michael Ellerman Cc: Shuah Khan Cc: Anton Blanchard Cc: Cyril Bur Cc: Anshuman Khandual Cc: Simon Guo Cc: Ulrich Weigand Cc: Michael Neuling Cc: Andrew Morton Cc: Kees Cook Cc: Rashmica Gupta Cc: Khem Raj Cc: Jessica Yu Cc: Jiri Kosina Cc: Miroslav Benes Cc: Suraj Jitindar Singh Cc: Chris Smart Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-kernel@vger.kernel.org Cc: linux-kselftest@vger.kernel.org Signed-off-by: Anshuman Khandual --- arch/powerpc/include/uapi/asm/elf.h | 1 + arch/powerpc/kernel/ptrace.c | 129 ++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) diff --git a/arch/powerpc/include/uapi/asm/elf.h b/arch/powerpc/include/uapi/asm/elf.h index ecb4e84..1549172 100644 --- a/arch/powerpc/include/uapi/asm/elf.h +++ b/arch/powerpc/include/uapi/asm/elf.h @@ -92,6 +92,7 @@ #define ELF_NGREG 48 /* includes nip, msr, lr, etc. */ #define ELF_NFPREG 33 /* includes fpscr */ #define ELF_NVMX 34 /* includes all vector registers */ +#define ELF_NVSX 32 /* includes all VSX registers */ typedef unsigned long elf_greg_t64; typedef elf_greg_t64 elf_gregset_t64[ELF_NGREG]; diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 836a4b4..c8bf7e9 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -65,6 +65,7 @@ struct pt_regs_offset { #define REG_OFFSET_END {.name = NULL, .offset = 0} #define TVSO(f) (offsetof(struct thread_vr_state, f)) +#define TFSO(f) (offsetof(struct thread_fp_state, f)) static const struct pt_regs_offset regoffset_table[] = { GPR_OFFSET_NAME(0), @@ -1294,6 +1295,123 @@ static int tm_cvmx_set(struct task_struct *target, return ret; } + +/** + * tm_cvsx_active - get active number of registers in CVSX + * @target: The target task. + * @regset: The user regset structure. + * + * This function checks for the active number of available + * regisers in transaction checkpointed VSX category. + */ +static int tm_cvsx_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; + + flush_vsx_to_thread(target); + return target->thread.used_vsr ? regset->n : 0; +} + +/** + * 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. + * + * This function gets in transaction checkpointed VSX 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 VSX registers. + * The userspace interface buffer layout is as follows. + * + * struct data { + * u64 vsx[32]; + *}; + */ +static int tm_cvsx_get(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + void *kbuf, void __user *ubuf) +{ + u64 buf[32]; + int ret, i; + + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return -ENODATA; + + /* Flush the state */ + flush_fp_to_thread(target); + flush_altivec_to_thread(target); + flush_tmregs_to_thread(target); + flush_vsx_to_thread(target); + + for (i = 0; i < 32 ; i++) + buf[i] = target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET]; + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + buf, 0, 32 * sizeof(double)); + + return ret; +} + +/** + * tm_cvsx_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 VSX registers. + * + * When the transaction is active 'fp_state' holds the checkpointed + * VSX 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 vsx[32]; + *}; + */ +static int tm_cvsx_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[32]; + int ret, i; + + if (!cpu_has_feature(CPU_FTR_TM)) + return -ENODEV; + + if (!MSR_TM_ACTIVE(target->thread.regs->msr)) + return -ENODATA; + + /* Flush the state */ + flush_fp_to_thread(target); + flush_altivec_to_thread(target); + flush_tmregs_to_thread(target); + flush_vsx_to_thread(target); + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + buf, 0, 32 * sizeof(double)); + for (i = 0; i < 32 ; i++) + target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i]; + + return ret; +} #endif /* @@ -1315,6 +1433,7 @@ enum powerpc_regset { REGSET_TM_CGPR, /* TM checkpointed GPR registers */ REGSET_TM_CFPR, /* TM checkpointed FPR registers */ REGSET_TM_CVMX, /* TM checkpointed VMX registers */ + REGSET_TM_CVSX, /* TM checkpointed VSX registers */ #endif }; @@ -1366,6 +1485,11 @@ static const struct user_regset native_regsets[] = { .size = sizeof(vector128), .align = sizeof(vector128), .active = tm_cvmx_active, .get = tm_cvmx_get, .set = tm_cvmx_set }, + [REGSET_TM_CVSX] = { + .core_note_type = NT_PPC_TM_CVSX, .n = ELF_NVSX, + .size = sizeof(double), .align = sizeof(double), + .active = tm_cvsx_active, .get = tm_cvsx_get, .set = tm_cvsx_set + }, #endif }; @@ -1608,6 +1732,11 @@ static const struct user_regset compat_regsets[] = { .size = sizeof(vector128), .align = sizeof(vector128), .active = tm_cvmx_active, .get = tm_cvmx_get, .set = tm_cvmx_set }, + [REGSET_TM_CVSX] = { + .core_note_type = NT_PPC_TM_CVSX, .n = ELF_NVSX, + .size = sizeof(double), .align = sizeof(double), + .active = tm_cvsx_active, .get = tm_cvsx_get, .set = tm_cvsx_set + }, #endif }; -- 1.8.3.1