[ARM] 5387/1: Add ptrace VFP support on ARM

This patch adds ptrace support for setting and getting the VFP registers
using PTRACE_SETVFPREGS and PTRACE_GETVFPREGS. The user_vfp structure
defined in asm/user.h contains 32 double registers (to cover VFPv3 and
Neon hardware) and the FPSCR register.

Cc: Paul Brook <paul@codesourcery.com>
Cc: Daniel Jacobowitz <dan@codesourcery.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
这个提交包含在:
Catalin Marinas
2009-02-11 13:12:56 +01:00
提交者 Russell King
父节点 f373e8c063
当前提交 3d1228ead6
修改 7 个文件,包含 120 行新增4 行删除

查看文件

@@ -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;