diff options
Diffstat (limited to 'arch/arm/kernel/ptrace.c')
-rw-r--r-- | arch/arm/kernel/ptrace.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index df653ea59250..89882a1d0187 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c | |||
@@ -653,6 +653,54 @@ static int ptrace_setcrunchregs(struct task_struct *tsk, void __user *ufp) | |||
653 | } | 653 | } |
654 | #endif | 654 | #endif |
655 | 655 | ||
656 | #ifdef CONFIG_VFP | ||
657 | /* | ||
658 | * Get the child VFP state. | ||
659 | */ | ||
660 | static int ptrace_getvfpregs(struct task_struct *tsk, void __user *data) | ||
661 | { | ||
662 | struct thread_info *thread = task_thread_info(tsk); | ||
663 | union vfp_state *vfp = &thread->vfpstate; | ||
664 | struct user_vfp __user *ufp = data; | ||
665 | |||
666 | vfp_sync_state(thread); | ||
667 | |||
668 | /* copy the floating point registers */ | ||
669 | if (copy_to_user(&ufp->fpregs, &vfp->hard.fpregs, | ||
670 | sizeof(vfp->hard.fpregs))) | ||
671 | return -EFAULT; | ||
672 | |||
673 | /* copy the status and control register */ | ||
674 | if (put_user(vfp->hard.fpscr, &ufp->fpscr)) | ||
675 | return -EFAULT; | ||
676 | |||
677 | return 0; | ||
678 | } | ||
679 | |||
680 | /* | ||
681 | * Set the child VFP state. | ||
682 | */ | ||
683 | static int ptrace_setvfpregs(struct task_struct *tsk, void __user *data) | ||
684 | { | ||
685 | struct thread_info *thread = task_thread_info(tsk); | ||
686 | union vfp_state *vfp = &thread->vfpstate; | ||
687 | struct user_vfp __user *ufp = data; | ||
688 | |||
689 | vfp_sync_state(thread); | ||
690 | |||
691 | /* copy the floating point registers */ | ||
692 | if (copy_from_user(&vfp->hard.fpregs, &ufp->fpregs, | ||
693 | sizeof(vfp->hard.fpregs))) | ||
694 | return -EFAULT; | ||
695 | |||
696 | /* copy the status and control register */ | ||
697 | if (get_user(vfp->hard.fpscr, &ufp->fpscr)) | ||
698 | return -EFAULT; | ||
699 | |||
700 | return 0; | ||
701 | } | ||
702 | #endif | ||
703 | |||
656 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 704 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) |
657 | { | 705 | { |
658 | int ret; | 706 | int ret; |
@@ -775,6 +823,16 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
775 | break; | 823 | break; |
776 | #endif | 824 | #endif |
777 | 825 | ||
826 | #ifdef CONFIG_VFP | ||
827 | case PTRACE_GETVFPREGS: | ||
828 | ret = ptrace_getvfpregs(child, (void __user *)data); | ||
829 | break; | ||
830 | |||
831 | case PTRACE_SETVFPREGS: | ||
832 | ret = ptrace_setvfpregs(child, (void __user *)data); | ||
833 | break; | ||
834 | #endif | ||
835 | |||
778 | default: | 836 | default: |
779 | ret = ptrace_request(child, request, addr, data); | 837 | ret = ptrace_request(child, request, addr, data); |
780 | break; | 838 | break; |