[PATCH] Add PTRACE_{GET|SET}VRREGS
Robert Jennings
rcjenn at austin.ibm.com
Fri Sep 9 05:04:01 EST 2005
The ptrace get and set methods for VMX/Altivec registers present in the
ppc tree were missing for ppc64. This patch adds the 32-bit and
64-bit methods. Updated with the suggestions from Anton following the lines
of his code snippet.
Added:
- flush_altivec_to_thread calls as suggested by Anton
- piecewise copy of structure to preserve 32-bit vrsave data as per
Anton
Appologies if this gets to the list twice, I had an MTA issue earlier.
Signed-off-by: Robert C Jennings <rcjenn at austin.ibm.com>
---
ptrace.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ptrace32.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 116 insertions(+)
diff -uprN -X linux-2.6.12.3.orig/Documentation/dontdiff linux-2.6.12.3.orig/arch/ppc64/kernel/ptrace32.c linux-2.6.12.3/arch/ppc64/kernel/ptrace32.c
--- linux-2.6.12.3.orig/arch/ppc64/kernel/ptrace32.c 2005-09-06 17:07:48.000000000 -0500
+++ linux-2.6.12.3/arch/ppc64/kernel/ptrace32.c 2005-09-06 17:12:11.735819943 -0500
@@ -409,6 +409,64 @@ int sys32_ptrace(long request, long pid,
ret = put_user(child->ptrace_message, (unsigned int __user *) data);
break;
+#ifdef CONFIG_ALTIVEC
+/*
+ * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
+ * The transfer totals 34 quadword. Quadwords 0-31 contain the
+ * corresponding vector registers. Quadword 32 contains the vscr as the
+ * last word (offset 12) within that quadword. Quadword 33 contains the
+ * vrsave as the first word (offset 0) within the quadword.
+ *
+ * This definition of the VMX state is compatible with the current PPC32
+ * ptrace interface. This allows signal handling and ptrace to use the
+ * same structures. This also simplifies the implementation of a bi-arch
+ * (combined (32- and 64-bit) gdb.
+ */
+ case PTRACE_GETVRREGS: {
+ flush_altivec_to_thread(child);
+
+ /* copy AltiVec registers VR[0] .. VR[31] */
+ unsigned long regsize;
+ regsize = 32 * sizeof(vector128);
+ if (copy_to_user((void *)data, &child->thread.vr, regsize))
+ return -EFAULT;
+ data += (regsize / sizeof(unsigned long));
+
+ /* copy VSCR */
+ regsize = 1 * sizeof(vector128);
+ if (copy_to_user((void *)data, &child->thread.vscr, regsize))
+ return -EFAULT;
+ data += (regsize / sizeof(unsigned long));
+
+ /* copy VRSAVE */
+ if (put_user(child->thread.vrsave, (u32 __user *)data))
+ return -EFAULT;
+ break;
+ }
+
+ case PTRACE_SETVRREGS: {
+ flush_altivec_to_thread(child);
+
+ /* copy AltiVec registers VR[0] .. VR[31] */
+ unsigned long regsize;
+ regsize = 32 * sizeof(vector128);
+ if (copy_from_user(&child->thread.vr, (void *)data, regsize))
+ return -EFAULT;
+ data += (regsize / sizeof(unsigned long));
+
+ /* copy VSCR */
+ regsize = 1 * sizeof(vector128);
+ if (copy_from_user(&child->thread.vscr, (void *)data, regsize))
+ return -EFAULT;
+ data += (regsize / sizeof(unsigned long));
+
+ /* copy VRSAVE */
+ if (get_user(child->thread.vrsave, (u32 __user *)data))
+ return -EFAULT;
+ break;
+ }
+#endif
+
default:
ret = ptrace_request(child, request, addr, data);
break;
diff -uprN -X linux-2.6.12.3.orig/Documentation/dontdiff linux-2.6.12.3.orig/arch/ppc64/kernel/ptrace.c linux-2.6.12.3/arch/ppc64/kernel/ptrace.c
--- linux-2.6.12.3.orig/arch/ppc64/kernel/ptrace.c 2005-09-06 17:07:34.000000000 -0500
+++ linux-2.6.12.3/arch/ppc64/kernel/ptrace.c 2005-09-06 17:11:54.202393173 -0500
@@ -274,6 +274,64 @@ int sys_ptrace(long request, long pid, l
break;
}
+#ifdef CONFIG_ALTIVEC
+/*
+ * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
+ * The transfer totals 34 quadword. Quadwords 0-31 contain the
+ * corresponding vector registers. Quadword 32 contains the vscr as the
+ * last word (offset 12) within that quadword. Quadword 33 contains the
+ * vrsave as the first word (offset 0) within the quadword.
+ *
+ * This definition of the VMX state is compatible with the current PPC32
+ * ptrace interface. This allows signal handling and ptrace to use the
+ * same structures. This also simplifies the implementation of a bi-arch
+ * (combined (32- and 64-bit) gdb.
+ */
+ case PTRACE_GETVRREGS: {
+ flush_altivec_to_thread(child);
+
+ /* copy AltiVec registers VR[0] .. VR[31] */
+ unsigned long regsize;
+ regsize = 32 * sizeof(vector128);
+ if (copy_to_user((void *)data, &child->thread.vr, regsize))
+ return -EFAULT;
+ data += (regsize / sizeof(unsigned long));
+
+ /* copy VSCR */
+ regsize = 1 * sizeof(vector128);
+ if (copy_to_user((void *)data, &child->thread.vscr, regsize))
+ return -EFAULT;
+ data += (regsize / sizeof(unsigned long));
+
+ /* copy VRSAVE */
+ if (put_user(child->thread.vrsave, (u32 __user *)data))
+ return -EFAULT;
+ break;
+ }
+
+ case PTRACE_SETVRREGS: {
+ flush_altivec_to_thread(child);
+
+ /* copy AltiVec registers VR[0] .. VR[31] */
+ unsigned long regsize;
+ regsize = 32 * sizeof(vector128);
+ if (copy_from_user(&child->thread.vr, (void *)data, regsize))
+ return -EFAULT;
+ data += (regsize / sizeof(unsigned long));
+
+ /* copy VSCR */
+ regsize = 1 * sizeof(vector128);
+ if (copy_from_user(&child->thread.vscr, (void *)data, regsize))
+ return -EFAULT;
+ data += (regsize / sizeof(unsigned long));
+
+ /* copy VRSAVE */
+ if (get_user(child->thread.vrsave, (u32 __user *)data))
+ return -EFAULT;
+ break;
+ }
+#endif
+
default:
ret = ptrace_request(child, request, addr, data);
break;
More information about the Linuxppc64-dev
mailing list