aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2012-07-06 10:50:14 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-07-09 12:44:14 -0400
commitad722541147e6e517a2077e3d944105e7bc4fa8e (patch)
treed69c7f9399e1407ec3300aa73b2467294972a087 /arch/arm/kernel
parent5125430cccc41f67bfe024394a302901034f6d39 (diff)
ARM: 7456/1: ptrace: provide separate functions for tracing syscall {entry,exit}
The syscall_trace on ARM takes a `why' parameter to indicate whether or not we are entering or exiting a system call. This can be confusing for people looking at the code since (a) it conflicts with the why register alias in the entry assembly code and (b) it is not immediately clear what it represents. This patch splits up the syscall_trace function into separate wrappers for syscall entry and exit, allowing the low-level syscall handling code to branch to the appropriate function. Reported-by: Al Viro <viro@zeniv.linux.org.uk> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel')
-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}