|
@@ -653,6 +653,54 @@ static int ptrace_setcrunchregs(struct task_struct *tsk, void __user *ufp)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+#ifdef CONFIG_VFP
|
|
|
+/*
|
|
|
+ * Get the child VFP state.
|
|
|
+ */
|
|
|
+static int ptrace_getvfpregs(struct task_struct *tsk, void __user *data)
|
|
|
+{
|
|
|
+ struct thread_info *thread = task_thread_info(tsk);
|
|
|
+ union vfp_state *vfp = &thread->vfpstate;
|
|
|
+ struct user_vfp __user *ufp = data;
|
|
|
+
|
|
|
+ vfp_sync_state(thread);
|
|
|
+
|
|
|
+ /* copy the floating point registers */
|
|
|
+ if (copy_to_user(&ufp->fpregs, &vfp->hard.fpregs,
|
|
|
+ sizeof(vfp->hard.fpregs)))
|
|
|
+ return -EFAULT;
|
|
|
+
|
|
|
+ /* copy the status and control register */
|
|
|
+ if (put_user(vfp->hard.fpscr, &ufp->fpscr))
|
|
|
+ return -EFAULT;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Set the child VFP state.
|
|
|
+ */
|
|
|
+static int ptrace_setvfpregs(struct task_struct *tsk, void __user *data)
|
|
|
+{
|
|
|
+ struct thread_info *thread = task_thread_info(tsk);
|
|
|
+ union vfp_state *vfp = &thread->vfpstate;
|
|
|
+ struct user_vfp __user *ufp = data;
|
|
|
+
|
|
|
+ vfp_sync_state(thread);
|
|
|
+
|
|
|
+ /* copy the floating point registers */
|
|
|
+ if (copy_from_user(&vfp->hard.fpregs, &ufp->fpregs,
|
|
|
+ sizeof(vfp->hard.fpregs)))
|
|
|
+ return -EFAULT;
|
|
|
+
|
|
|
+ /* copy the status and control register */
|
|
|
+ if (get_user(vfp->hard.fpscr, &ufp->fpscr))
|
|
|
+ return -EFAULT;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
|
|
{
|
|
|
int ret;
|
|
@@ -775,6 +823,16 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
|
|
break;
|
|
|
#endif
|
|
|
|
|
|
+#ifdef CONFIG_VFP
|
|
|
+ case PTRACE_GETVFPREGS:
|
|
|
+ ret = ptrace_getvfpregs(child, (void __user *)data);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case PTRACE_SETVFPREGS:
|
|
|
+ ret = ptrace_setvfpregs(child, (void __user *)data);
|
|
|
+ break;
|
|
|
+#endif
|
|
|
+
|
|
|
default:
|
|
|
ret = ptrace_request(child, request, addr, data);
|
|
|
break;
|