[PATCH] ppc64: Add PTRACE_{GET|SET}VRREGS

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

(I consolidated the 32 and 64bit versions with 2 helper macros - Anton)

Signed-off-by: Robert C Jennings <rcjenn@austin.ibm.com>
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
diff --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c
index 2993f10..bf7116d 100644
--- a/arch/ppc64/kernel/ptrace.c
+++ b/arch/ppc64/kernel/ptrace.c
@@ -17,6 +17,7 @@
  * this archive for more details.
  */
 
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
@@ -274,6 +275,20 @@
 		break;
 	}
 
+#ifdef CONFIG_ALTIVEC
+	case PTRACE_GETVRREGS:
+		/* Get the child altivec register state. */
+		flush_altivec_to_thread(child);
+		ret = get_vrregs((unsigned long __user *)data, child);
+		break;
+
+	case PTRACE_SETVRREGS:
+		/* Set the child altivec register state. */
+		flush_altivec_to_thread(child);
+		ret = set_vrregs(child, (unsigned long __user *)data);
+		break;
+#endif
+
 	default:
 		ret = ptrace_request(child, request, addr, data);
 		break;
diff --git a/arch/ppc64/kernel/ptrace32.c b/arch/ppc64/kernel/ptrace32.c
index 1643642..4d1568c 100644
--- a/arch/ppc64/kernel/ptrace32.c
+++ b/arch/ppc64/kernel/ptrace32.c
@@ -17,6 +17,7 @@
  * this archive for more details.
  */
 
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
@@ -409,6 +410,20 @@
                 ret = put_user(child->ptrace_message, (unsigned int __user *) data);
                 break;
 
+#ifdef CONFIG_ALTIVEC
+	case PTRACE_GETVRREGS:
+		/* Get the child altivec register state. */
+		flush_altivec_to_thread(child);
+		ret = get_vrregs((unsigned long __user *)data, child);
+		break;
+
+	case PTRACE_SETVRREGS:
+		/* Set the child altivec register state. */
+		flush_altivec_to_thread(child);
+		ret = set_vrregs(child, (unsigned long __user *)data);
+		break;
+#endif
+
 	default:
 		ret = ptrace_request(child, request, addr, data);
 		break;