diff options
author | Wade Farnsworth <wade_farnsworth@mentor.com> | 2012-09-07 13:18:25 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-09-19 16:50:48 -0400 |
commit | 1f66e06fb6414732bef7bf4a071ef76a837badec (patch) | |
tree | 329bd62fd3ce0c1f55242549f8486f5b168f4bce /arch | |
parent | 5698bd757d55b1bb87edd1a9744ab09c142abfc2 (diff) |
ARM: 7524/1: support syscall tracing
As specified by ftrace-design.txt, TIF_SYSCALL_TRACEPOINT was
added, as well as NR_syscalls in asm/unistd.h. Additionally,
__sys_trace was modified to call trace_sys_enter and
trace_sys_exit when appropriate.
Tests #2 - #4 of "perf test" now complete successfully.
Signed-off-by: Steven Walter <stevenrwalter@gmail.com>
Signed-off-by: Wade Farnsworth <wade_farnsworth@mentor.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')
-rw-r--r-- | arch/arm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/include/asm/syscall.h | 4 | ||||
-rw-r--r-- | arch/arm/include/asm/thread_info.h | 4 | ||||
-rw-r--r-- | arch/arm/include/asm/unistd.h | 8 | ||||
-rw-r--r-- | arch/arm/kernel/entry-common.S | 9 | ||||
-rw-r--r-- | arch/arm/kernel/ptrace.c | 11 |
6 files changed, 34 insertions, 3 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 2f88d8d97701..1382ef1142a3 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -16,6 +16,7 @@ config ARM | |||
16 | select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL | 16 | select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL |
17 | select HAVE_ARCH_KGDB | 17 | select HAVE_ARCH_KGDB |
18 | select HAVE_ARCH_TRACEHOOK | 18 | select HAVE_ARCH_TRACEHOOK |
19 | select HAVE_SYSCALL_TRACEPOINTS | ||
19 | select HAVE_KPROBES if !XIP_KERNEL | 20 | select HAVE_KPROBES if !XIP_KERNEL |
20 | select HAVE_KRETPROBES if (HAVE_KPROBES) | 21 | select HAVE_KRETPROBES if (HAVE_KPROBES) |
21 | select HAVE_FUNCTION_TRACER if (!XIP_KERNEL) | 22 | select HAVE_FUNCTION_TRACER if (!XIP_KERNEL) |
diff --git a/arch/arm/include/asm/syscall.h b/arch/arm/include/asm/syscall.h index c334a23ddf75..47486a41c56e 100644 --- a/arch/arm/include/asm/syscall.h +++ b/arch/arm/include/asm/syscall.h | |||
@@ -9,6 +9,10 @@ | |||
9 | 9 | ||
10 | #include <linux/err.h> | 10 | #include <linux/err.h> |
11 | 11 | ||
12 | #include <asm/unistd.h> | ||
13 | |||
14 | #define NR_syscalls (__NR_syscalls) | ||
15 | |||
12 | extern const unsigned long sys_call_table[]; | 16 | extern const unsigned long sys_call_table[]; |
13 | 17 | ||
14 | static inline int syscall_get_nr(struct task_struct *task, | 18 | static inline int syscall_get_nr(struct task_struct *task, |
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index af7b0bda3355..5ded667e330f 100644 --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h | |||
@@ -148,6 +148,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, | |||
148 | #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ | 148 | #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ |
149 | #define TIF_SYSCALL_TRACE 8 | 149 | #define TIF_SYSCALL_TRACE 8 |
150 | #define TIF_SYSCALL_AUDIT 9 | 150 | #define TIF_SYSCALL_AUDIT 9 |
151 | #define TIF_SYSCALL_TRACEPOINT 10 | ||
151 | #define TIF_POLLING_NRFLAG 16 | 152 | #define TIF_POLLING_NRFLAG 16 |
152 | #define TIF_USING_IWMMXT 17 | 153 | #define TIF_USING_IWMMXT 17 |
153 | #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ | 154 | #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ |
@@ -160,12 +161,13 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, | |||
160 | #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) | 161 | #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) |
161 | #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) | 162 | #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) |
162 | #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) | 163 | #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) |
164 | #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) | ||
163 | #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) | 165 | #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) |
164 | #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) | 166 | #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) |
165 | #define _TIF_SECCOMP (1 << TIF_SECCOMP) | 167 | #define _TIF_SECCOMP (1 << TIF_SECCOMP) |
166 | 168 | ||
167 | /* Checks for any syscall work in entry-common.S */ | 169 | /* Checks for any syscall work in entry-common.S */ |
168 | #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT) | 170 | #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SYSCALL_TRACEPOINT) |
169 | 171 | ||
170 | /* | 172 | /* |
171 | * Change these and you break ASM code in entry-common.S | 173 | * Change these and you break ASM code in entry-common.S |
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h index 0cab47d4a83f..a566ec20d486 100644 --- a/arch/arm/include/asm/unistd.h +++ b/arch/arm/include/asm/unistd.h | |||
@@ -406,6 +406,14 @@ | |||
406 | #define __NR_process_vm_writev (__NR_SYSCALL_BASE+377) | 406 | #define __NR_process_vm_writev (__NR_SYSCALL_BASE+377) |
407 | 407 | ||
408 | /* | 408 | /* |
409 | * This may need to be greater than __NR_last_syscall+1 in order to | ||
410 | * account for the padding in the syscall table | ||
411 | */ | ||
412 | #ifdef __KERNEL__ | ||
413 | #define __NR_syscalls (380) | ||
414 | #endif /* __KERNEL__ */ | ||
415 | |||
416 | /* | ||
409 | * The following SWIs are ARM private. | 417 | * The following SWIs are ARM private. |
410 | */ | 418 | */ |
411 | #define __ARM_NR_BASE (__NR_SYSCALL_BASE+0x0f0000) | 419 | #define __ARM_NR_BASE (__NR_SYSCALL_BASE+0x0f0000) |
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 978eac57e04a..f45987037bf1 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
@@ -94,6 +94,15 @@ ENDPROC(ret_from_fork) | |||
94 | .equ NR_syscalls,0 | 94 | .equ NR_syscalls,0 |
95 | #define CALL(x) .equ NR_syscalls,NR_syscalls+1 | 95 | #define CALL(x) .equ NR_syscalls,NR_syscalls+1 |
96 | #include "calls.S" | 96 | #include "calls.S" |
97 | |||
98 | /* | ||
99 | * Ensure that the system call table is equal to __NR_syscalls, | ||
100 | * which is the value the rest of the system sees | ||
101 | */ | ||
102 | .ifne NR_syscalls - __NR_syscalls | ||
103 | .error "__NR_syscalls is not equal to the size of the syscall table" | ||
104 | .endif | ||
105 | |||
97 | #undef CALL | 106 | #undef CALL |
98 | #define CALL(x) .long x | 107 | #define CALL(x) .long x |
99 | 108 | ||
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 3e0fc5f7ed4b..c382d3c76ac6 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c | |||
@@ -30,6 +30,9 @@ | |||
30 | #include <asm/pgtable.h> | 30 | #include <asm/pgtable.h> |
31 | #include <asm/traps.h> | 31 | #include <asm/traps.h> |
32 | 32 | ||
33 | #define CREATE_TRACE_POINTS | ||
34 | #include <trace/events/syscalls.h> | ||
35 | |||
33 | #define REG_PC 15 | 36 | #define REG_PC 15 |
34 | #define REG_PSR 16 | 37 | #define REG_PSR 16 |
35 | /* | 38 | /* |
@@ -918,11 +921,11 @@ static int ptrace_syscall_trace(struct pt_regs *regs, int scno, | |||
918 | { | 921 | { |
919 | unsigned long ip; | 922 | unsigned long ip; |
920 | 923 | ||
924 | current_thread_info()->syscall = scno; | ||
925 | |||
921 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) | 926 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) |
922 | return scno; | 927 | return scno; |
923 | 928 | ||
924 | current_thread_info()->syscall = scno; | ||
925 | |||
926 | /* | 929 | /* |
927 | * IP is used to denote syscall entry/exit: | 930 | * IP is used to denote syscall entry/exit: |
928 | * IP = 0 -> entry, =1 -> exit | 931 | * IP = 0 -> entry, =1 -> exit |
@@ -942,6 +945,8 @@ static int ptrace_syscall_trace(struct pt_regs *regs, int scno, | |||
942 | asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno) | 945 | asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno) |
943 | { | 946 | { |
944 | int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_ENTER); | 947 | int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_ENTER); |
948 | if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) | ||
949 | trace_sys_enter(regs, ret); | ||
945 | audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1, | 950 | audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1, |
946 | regs->ARM_r2, regs->ARM_r3); | 951 | regs->ARM_r2, regs->ARM_r3); |
947 | return ret; | 952 | return ret; |
@@ -950,6 +955,8 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno) | |||
950 | asmlinkage int syscall_trace_exit(struct pt_regs *regs, int scno) | 955 | asmlinkage int syscall_trace_exit(struct pt_regs *regs, int scno) |
951 | { | 956 | { |
952 | int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_EXIT); | 957 | int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_EXIT); |
958 | if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) | ||
959 | trace_sys_exit(regs, ret); | ||
953 | audit_syscall_exit(regs); | 960 | audit_syscall_exit(regs); |
954 | return ret; | 961 | return ret; |
955 | } | 962 | } |