Inter-revision diff: patch 5

Comparing v11 (message) to v12 (message)

--- v11
+++ v12
@@ -1,12 +1,11 @@
 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.
+This patch enables in transaction NT_PPC_VSX ptrace requests. The
+function vsr_get which gets the running value of all VSX registers
+and the function vsr_set which sets the running value of of all VSX
+registers work on the running set of VMX registers whose location
+will be different if transaction is active. This patch makes these
+functions adapt to situations when the transaction is active.
 
 Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
 Cc: Paul Mackerras <paulus@samba.org>
@@ -31,168 +30,114 @@
 Cc: linux-kernel@vger.kernel.org
 Cc: linux-kselftest@vger.kernel.org
 Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
-Signed-off-by: Simon Guo <wei.guo.simon@gmail.com>
 ---
- arch/powerpc/kernel/ptrace.c | 126 +++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 126 insertions(+)
+ arch/powerpc/kernel/ptrace.c | 64 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 64 insertions(+)
 
 diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
-index 0334c23..a3d4bad 100644
+index 3baa57e..ebf3b0e 100644
 --- a/arch/powerpc/kernel/ptrace.c
 +++ b/arch/powerpc/kernel/ptrace.c
-@@ -799,6 +799,121 @@ static int tm_cgpr_set(struct task_struct *target,
+@@ -681,6 +681,21 @@ static int vsr_active(struct task_struct *target,
+ 	return target->thread.used_vsr ? regset->n : 0;
+ }
+ 
++/*
++ * When the transaction is active, 'transact_fp' holds the current running
++ * value of all FPR registers and 'fp_state' holds the last checkpointed
++ * value of all FPR registers for the current transaction. When transaction
++ * is not active 'fp_state' holds the current running state of all the FPR
++ * registers. So this function which returns the current running values of
++ * all the FPR registers, needs to know whether any transaction is active
++ * or not.
++ *
++ * Userspace interface buffer layout:
++ *
++ * struct data {
++ *	u64	vsx[32];
++ * };
++ */
+ static int vsr_get(struct task_struct *target, const struct user_regset *regset,
+ 		   unsigned int pos, unsigned int count,
+ 		   void *kbuf, void __user *ubuf)
+@@ -688,16 +703,47 @@ static int vsr_get(struct task_struct *target, const struct user_regset *regset,
+ 	u64 buf[32];
+ 	int ret, i;
+ 
++#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
++	flush_fp_to_thread(target);
++	flush_altivec_to_thread(target);
++	flush_tmregs_to_thread(target);
++#endif
+ 	flush_vsx_to_thread(target);
+ 
++#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
++	if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
++		for (i = 0; i < 32 ; i++)
++			buf[i] = target->thread.
++				transact_fp.fpr[i][TS_VSRLOWOFFSET];
++	} else {
++		for (i = 0; i < 32 ; i++)
++			buf[i] = target->thread.
++				fp_state.fpr[i][TS_VSRLOWOFFSET];
++	}
++#else
+ 	for (i = 0; i < 32 ; i++)
+ 		buf[i] = target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
++#endif
+ 	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ 				  buf, 0, 32 * sizeof(double));
  
  	return ret;
  }
-+
-+/**
-+ * tm_cfpr_active - get active number of registers in CFPR
-+ * @target:	The target task.
-+ * @regset:	The user regset structure.
+ 
++/*
++ * When the transaction is active, 'transact_fp' holds the current running
++ * value of all FPR registers and 'fp_state' holds the last checkpointed
++ * value of all FPR registers for the current transaction. When transaction
++ * is not active 'fp_state' holds the current running state of all the FPR
++ * registers. So this function which sets the current running values of all
++ * the FPR registers, needs to know whether any transaction is active or not.
 + *
-+ * 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 'ckfp_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.
++ * Userspace interface buffer layout:
 + *
 + * struct data {
-+ *	u64	fpr[32];
-+ *	u64	fpscr;
-+ *};
++ *	u64	vsx[32];
++ * };
 + */
-+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;
-+
+ static int vsr_set(struct task_struct *target, const struct user_regset *regset,
+ 		   unsigned int pos, unsigned int count,
+ 		   const void *kbuf, const void __user *ubuf)
+@@ -705,12 +751,30 @@ static int vsr_set(struct task_struct *target, const struct user_regset *regset,
+ 	u64 buf[32];
+ 	int ret,i;
+ 
++#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
 +	flush_fp_to_thread(target);
 +	flush_altivec_to_thread(target);
 +	flush_tmregs_to_thread(target);
++#endif
+ 	flush_vsx_to_thread(target);
+ 
+ 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ 				 buf, 0, 32 * sizeof(double));
 +
-+	/* copy to local buffer then write that out */
-+	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);
-+}
-+
-+/**
-+ * 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 'ckfp_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_CKFPR(i) = buf[i];
-+	target->thread.ckfp_state.fpscr = buf[32];
-+	return 0;
-+}
- #endif
++#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
++	if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
++		for (i = 0; i < 32 ; i++)
++			target->thread.transact_fp.
++				fpr[i][TS_VSRLOWOFFSET] = buf[i];
++	} else {
++		for (i = 0; i < 32 ; i++)
++			target->thread.fp_state.
++				fpr[i][TS_VSRLOWOFFSET] = buf[i];
++	}
++#else
+ 	for (i = 0; i < 32 ; i++)
+ 		target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
++#endif
  
- /*
-@@ -818,6 +933,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
- };
  
-@@ -859,6 +975,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
- };
- 
-@@ -1091,6 +1212,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
- };
- 
+ 	return ret;
 -- 
 1.8.3.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help