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>
This commit is contained in:
Wade Farnsworth 2012-09-07 18:18:25 +01:00 коммит произвёл Russell King
Родитель 5698bd757d
Коммит 1f66e06fb6
6 изменённых файлов: 34 добавлений и 3 удалений

Просмотреть файл

@ -16,6 +16,7 @@ config ARM
select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
select HAVE_ARCH_KGDB select HAVE_ARCH_KGDB
select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRACEHOOK
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_KPROBES if !XIP_KERNEL select HAVE_KPROBES if !XIP_KERNEL
select HAVE_KRETPROBES if (HAVE_KPROBES) select HAVE_KRETPROBES if (HAVE_KPROBES)
select HAVE_FUNCTION_TRACER if (!XIP_KERNEL) select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)

Просмотреть файл

@ -9,6 +9,10 @@
#include <linux/err.h> #include <linux/err.h>
#include <asm/unistd.h>
#define NR_syscalls (__NR_syscalls)
extern const unsigned long sys_call_table[]; extern const unsigned long sys_call_table[];
static inline int syscall_get_nr(struct task_struct *task, static inline int syscall_get_nr(struct task_struct *task,

Просмотреть файл

@ -148,6 +148,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
#define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */
#define TIF_SYSCALL_TRACE 8 #define TIF_SYSCALL_TRACE 8
#define TIF_SYSCALL_AUDIT 9 #define TIF_SYSCALL_AUDIT 9
#define TIF_SYSCALL_TRACEPOINT 10
#define TIF_POLLING_NRFLAG 16 #define TIF_POLLING_NRFLAG 16
#define TIF_USING_IWMMXT 17 #define TIF_USING_IWMMXT 17
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_MEMDIE 18 /* is terminating due to OOM killer */
@ -160,12 +161,13 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_SECCOMP (1 << TIF_SECCOMP)
/* Checks for any syscall work in entry-common.S */ /* Checks for any syscall work in entry-common.S */
#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SYSCALL_TRACEPOINT)
/* /*
* Change these and you break ASM code in entry-common.S * Change these and you break ASM code in entry-common.S

Просмотреть файл

@ -405,6 +405,14 @@
#define __NR_process_vm_readv (__NR_SYSCALL_BASE+376) #define __NR_process_vm_readv (__NR_SYSCALL_BASE+376)
#define __NR_process_vm_writev (__NR_SYSCALL_BASE+377) #define __NR_process_vm_writev (__NR_SYSCALL_BASE+377)
/*
* This may need to be greater than __NR_last_syscall+1 in order to
* account for the padding in the syscall table
*/
#ifdef __KERNEL__
#define __NR_syscalls (380)
#endif /* __KERNEL__ */
/* /*
* The following SWIs are ARM private. * The following SWIs are ARM private.
*/ */

Просмотреть файл

@ -94,6 +94,15 @@ ENDPROC(ret_from_fork)
.equ NR_syscalls,0 .equ NR_syscalls,0
#define CALL(x) .equ NR_syscalls,NR_syscalls+1 #define CALL(x) .equ NR_syscalls,NR_syscalls+1
#include "calls.S" #include "calls.S"
/*
* Ensure that the system call table is equal to __NR_syscalls,
* which is the value the rest of the system sees
*/
.ifne NR_syscalls - __NR_syscalls
.error "__NR_syscalls is not equal to the size of the syscall table"
.endif
#undef CALL #undef CALL
#define CALL(x) .long x #define CALL(x) .long x

Просмотреть файл

@ -30,6 +30,9 @@
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/traps.h> #include <asm/traps.h>
#define CREATE_TRACE_POINTS
#include <trace/events/syscalls.h>
#define REG_PC 15 #define REG_PC 15
#define REG_PSR 16 #define REG_PSR 16
/* /*
@ -918,11 +921,11 @@ static int ptrace_syscall_trace(struct pt_regs *regs, int scno,
{ {
unsigned long ip; unsigned long ip;
current_thread_info()->syscall = scno;
if (!test_thread_flag(TIF_SYSCALL_TRACE)) if (!test_thread_flag(TIF_SYSCALL_TRACE))
return scno; return scno;
current_thread_info()->syscall = scno;
/* /*
* IP is used to denote syscall entry/exit: * IP is used to denote syscall entry/exit:
* IP = 0 -> entry, =1 -> exit * IP = 0 -> entry, =1 -> exit
@ -942,6 +945,8 @@ static int ptrace_syscall_trace(struct pt_regs *regs, int scno,
asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno) asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
{ {
int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_ENTER); int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_ENTER);
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
trace_sys_enter(regs, ret);
audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1, audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1,
regs->ARM_r2, regs->ARM_r3); regs->ARM_r2, regs->ARM_r3);
return ret; return ret;
@ -950,6 +955,8 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
asmlinkage int syscall_trace_exit(struct pt_regs *regs, int scno) asmlinkage int syscall_trace_exit(struct pt_regs *regs, int scno)
{ {
int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_EXIT); int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_EXIT);
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
trace_sys_exit(regs, ret);
audit_syscall_exit(regs); audit_syscall_exit(regs);
return ret; return ret;
} }