diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-02-25 17:09:41 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-02-25 17:09:41 -0500 |
commit | 2741ecb4ce5c2d430b5c44b0a169038338c21df5 (patch) | |
tree | 4aa71d7551184ee88f32c7f3660d821133058c32 /arch/arm/kernel/ptrace.c | |
parent | bc85e585c6d0fab4bde12d60964b2f25802c3163 (diff) | |
parent | 5de813b6cd06460b337f9da9afe316823cf3ef45 (diff) |
Merge branch 'misc2' into devel
Diffstat (limited to 'arch/arm/kernel/ptrace.c')
-rw-r--r-- | arch/arm/kernel/ptrace.c | 53 |
1 files changed, 35 insertions, 18 deletions
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index a2ea3854cb3c..08f899fb76a6 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c | |||
@@ -499,10 +499,41 @@ static struct undef_hook thumb_break_hook = { | |||
499 | .fn = break_trap, | 499 | .fn = break_trap, |
500 | }; | 500 | }; |
501 | 501 | ||
502 | static int thumb2_break_trap(struct pt_regs *regs, unsigned int instr) | ||
503 | { | ||
504 | unsigned int instr2; | ||
505 | void __user *pc; | ||
506 | |||
507 | /* Check the second half of the instruction. */ | ||
508 | pc = (void __user *)(instruction_pointer(regs) + 2); | ||
509 | |||
510 | if (processor_mode(regs) == SVC_MODE) { | ||
511 | instr2 = *(u16 *) pc; | ||
512 | } else { | ||
513 | get_user(instr2, (u16 __user *)pc); | ||
514 | } | ||
515 | |||
516 | if (instr2 == 0xa000) { | ||
517 | ptrace_break(current, regs); | ||
518 | return 0; | ||
519 | } else { | ||
520 | return 1; | ||
521 | } | ||
522 | } | ||
523 | |||
524 | static struct undef_hook thumb2_break_hook = { | ||
525 | .instr_mask = 0xffff, | ||
526 | .instr_val = 0xf7f0, | ||
527 | .cpsr_mask = PSR_T_BIT, | ||
528 | .cpsr_val = PSR_T_BIT, | ||
529 | .fn = thumb2_break_trap, | ||
530 | }; | ||
531 | |||
502 | static int __init ptrace_break_init(void) | 532 | static int __init ptrace_break_init(void) |
503 | { | 533 | { |
504 | register_undef_hook(&arm_break_hook); | 534 | register_undef_hook(&arm_break_hook); |
505 | register_undef_hook(&thumb_break_hook); | 535 | register_undef_hook(&thumb_break_hook); |
536 | register_undef_hook(&thumb2_break_hook); | ||
506 | return 0; | 537 | return 0; |
507 | } | 538 | } |
508 | 539 | ||
@@ -669,7 +700,7 @@ static int ptrace_getvfpregs(struct task_struct *tsk, void __user *data) | |||
669 | union vfp_state *vfp = &thread->vfpstate; | 700 | union vfp_state *vfp = &thread->vfpstate; |
670 | struct user_vfp __user *ufp = data; | 701 | struct user_vfp __user *ufp = data; |
671 | 702 | ||
672 | vfp_sync_state(thread); | 703 | vfp_sync_hwstate(thread); |
673 | 704 | ||
674 | /* copy the floating point registers */ | 705 | /* copy the floating point registers */ |
675 | if (copy_to_user(&ufp->fpregs, &vfp->hard.fpregs, | 706 | if (copy_to_user(&ufp->fpregs, &vfp->hard.fpregs, |
@@ -692,7 +723,7 @@ static int ptrace_setvfpregs(struct task_struct *tsk, void __user *data) | |||
692 | union vfp_state *vfp = &thread->vfpstate; | 723 | union vfp_state *vfp = &thread->vfpstate; |
693 | struct user_vfp __user *ufp = data; | 724 | struct user_vfp __user *ufp = data; |
694 | 725 | ||
695 | vfp_sync_state(thread); | 726 | vfp_sync_hwstate(thread); |
696 | 727 | ||
697 | /* copy the floating point registers */ | 728 | /* copy the floating point registers */ |
698 | if (copy_from_user(&vfp->hard.fpregs, &ufp->fpregs, | 729 | if (copy_from_user(&vfp->hard.fpregs, &ufp->fpregs, |
@@ -703,6 +734,8 @@ static int ptrace_setvfpregs(struct task_struct *tsk, void __user *data) | |||
703 | if (get_user(vfp->hard.fpscr, &ufp->fpscr)) | 734 | if (get_user(vfp->hard.fpscr, &ufp->fpscr)) |
704 | return -EFAULT; | 735 | return -EFAULT; |
705 | 736 | ||
737 | vfp_flush_hwstate(thread); | ||
738 | |||
706 | return 0; | 739 | return 0; |
707 | } | 740 | } |
708 | #endif | 741 | #endif |
@@ -712,26 +745,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
712 | int ret; | 745 | int ret; |
713 | 746 | ||
714 | switch (request) { | 747 | switch (request) { |
715 | /* | ||
716 | * read word at location "addr" in the child process. | ||
717 | */ | ||
718 | case PTRACE_PEEKTEXT: | ||
719 | case PTRACE_PEEKDATA: | ||
720 | ret = generic_ptrace_peekdata(child, addr, data); | ||
721 | break; | ||
722 | |||
723 | case PTRACE_PEEKUSR: | 748 | case PTRACE_PEEKUSR: |
724 | ret = ptrace_read_user(child, addr, (unsigned long __user *)data); | 749 | ret = ptrace_read_user(child, addr, (unsigned long __user *)data); |
725 | break; | 750 | break; |
726 | 751 | ||
727 | /* | ||
728 | * write the word at location addr. | ||
729 | */ | ||
730 | case PTRACE_POKETEXT: | ||
731 | case PTRACE_POKEDATA: | ||
732 | ret = generic_ptrace_pokedata(child, addr, data); | ||
733 | break; | ||
734 | |||
735 | case PTRACE_POKEUSR: | 752 | case PTRACE_POKEUSR: |
736 | ret = ptrace_write_user(child, addr, data); | 753 | ret = ptrace_write_user(child, addr, data); |
737 | break; | 754 | break; |