aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/kernel/entry-common.S14
-rw-r--r--arch/arm/kernel/ptrace.c37
2 files changed, 31 insertions, 20 deletions
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 10911c93fbf1..49d9f9305247 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -442,10 +442,9 @@ ENDPROC(vector_swi)
442 * context switches, and waiting for our parent to respond. 442 * context switches, and waiting for our parent to respond.
443 */ 443 */
444__sys_trace: 444__sys_trace:
445 mov r2, scno 445 mov r1, scno
446 add r1, sp, #S_OFF 446 add r0, sp, #S_OFF
447 mov r0, #0 @ trace entry [IP = 0] 447 bl syscall_trace_enter
448 bl syscall_trace
449 448
450 adr lr, BSYM(__sys_trace_return) @ return address 449 adr lr, BSYM(__sys_trace_return) @ return address
451 mov scno, r0 @ syscall number (possibly new) 450 mov scno, r0 @ syscall number (possibly new)
@@ -457,10 +456,9 @@ __sys_trace:
457 456
458__sys_trace_return: 457__sys_trace_return:
459 str r0, [sp, #S_R0 + S_OFF]! @ save returned r0 458 str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
460 mov r2, scno 459 mov r1, scno
461 mov r1, sp 460 mov r0, sp
462 mov r0, #1 @ trace exit [IP = 1] 461 bl syscall_trace_exit
463 bl syscall_trace
464 b ret_slow_syscall 462 b ret_slow_syscall
465 463
466 .align 5 464 .align 5
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 592a39d0ef31..dab711e6e1ca 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -907,12 +907,18 @@ long arch_ptrace(struct task_struct *child, long request,
907 return ret; 907 return ret;
908} 908}
909 909
910asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) 910enum ptrace_syscall_dir {
911 PTRACE_SYSCALL_ENTER = 0,
912 PTRACE_SYSCALL_EXIT,
913};
914
915static int ptrace_syscall_trace(struct pt_regs *regs, int scno,
916 enum ptrace_syscall_dir dir)
911{ 917{
912 unsigned long ip; 918 unsigned long ip;
913 919
914 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 920 if (!test_thread_flag(TIF_SYSCALL_TRACE))
915 goto out_no_trace; 921 return scno;
916 922
917 current_thread_info()->syscall = scno; 923 current_thread_info()->syscall = scno;
918 924
@@ -921,21 +927,28 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
921 * IP = 0 -> entry, =1 -> exit 927 * IP = 0 -> entry, =1 -> exit
922 */ 928 */
923 ip = regs->ARM_ip; 929 ip = regs->ARM_ip;
924 regs->ARM_ip = why; 930 regs->ARM_ip = dir;
925 931
926 if (why) 932 if (dir == PTRACE_SYSCALL_EXIT)
927 tracehook_report_syscall_exit(regs, 0); 933 tracehook_report_syscall_exit(regs, 0);
928 else if (tracehook_report_syscall_entry(regs)) 934 else if (tracehook_report_syscall_entry(regs))
929 current_thread_info()->syscall = -1; 935 current_thread_info()->syscall = -1;
930 936
931 regs->ARM_ip = ip; 937 regs->ARM_ip = ip;
932 scno = current_thread_info()->syscall; 938 return current_thread_info()->syscall;
939}
933 940
934out_no_trace: 941asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
935 if (why) 942{
936 audit_syscall_exit(regs); 943 int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_ENTER);
937 else 944 audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1,
938 audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, 945 regs->ARM_r2, regs->ARM_r3);
939 regs->ARM_r1, regs->ARM_r2, regs->ARM_r3); 946 return ret;
940 return scno; 947}
948
949asmlinkage int syscall_trace_exit(struct pt_regs *regs, int scno)
950{
951 int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_EXIT);
952 audit_syscall_exit(regs);
953 return ret;
941} 954}