diff options
| author | Jason Baron <jbaron@redhat.com> | 2009-08-10 16:52:31 -0400 |
|---|---|---|
| committer | Frederic Weisbecker <fweisbec@gmail.com> | 2009-08-11 14:35:26 -0400 |
| commit | a871bd33a6c0bc86fb47cd02ea2650dd43d3d95f (patch) | |
| tree | b5720cdb3168ba0894b4bd2c1acc004cb19a692c | |
| parent | 63fbdab3157b72467013fe4dcf88c85e45280ef7 (diff) | |
tracing: Add syscall tracepoints
add two tracepoints in syscall exit and entry path, conditioned on
TIF_SYSCALL_FTRACE. Supports the syscall trace event code.
Signed-off-by: Jason Baron <jbaron@redhat.com>
Cc: Lai Jiangshan <laijs@cn.fujitsu.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Cc: Jiaying Zhang <jiayingz@google.com>
Cc: Martin Bligh <mbligh@google.com>
Cc: Li Zefan <lizf@cn.fujitsu.com>
Cc: Masami Hiramatsu <mhiramat@redhat.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
| -rw-r--r-- | arch/x86/kernel/ptrace.c | 7 | ||||
| -rw-r--r-- | include/trace/syscall.h | 20 | ||||
| -rw-r--r-- | kernel/tracepoint.c | 38 |
3 files changed, 63 insertions, 2 deletions
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 09ecbde91c13..34dd6f15185d 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c | |||
| @@ -37,6 +37,9 @@ | |||
| 37 | 37 | ||
| 38 | #include <trace/syscall.h> | 38 | #include <trace/syscall.h> |
| 39 | 39 | ||
| 40 | DEFINE_TRACE(syscall_enter); | ||
| 41 | DEFINE_TRACE(syscall_exit); | ||
| 42 | |||
| 40 | #include "tls.h" | 43 | #include "tls.h" |
| 41 | 44 | ||
| 42 | enum x86_regset { | 45 | enum x86_regset { |
| @@ -1498,7 +1501,7 @@ asmregparm long syscall_trace_enter(struct pt_regs *regs) | |||
| 1498 | ret = -1L; | 1501 | ret = -1L; |
| 1499 | 1502 | ||
| 1500 | if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) | 1503 | if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) |
| 1501 | ftrace_syscall_enter(regs); | 1504 | trace_syscall_enter(regs, regs->orig_ax); |
| 1502 | 1505 | ||
| 1503 | if (unlikely(current->audit_context)) { | 1506 | if (unlikely(current->audit_context)) { |
| 1504 | if (IS_IA32) | 1507 | if (IS_IA32) |
| @@ -1524,7 +1527,7 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs) | |||
| 1524 | audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax); | 1527 | audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax); |
| 1525 | 1528 | ||
| 1526 | if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) | 1529 | if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) |
| 1527 | ftrace_syscall_exit(regs); | 1530 | trace_syscall_exit(regs, regs->ax); |
| 1528 | 1531 | ||
| 1529 | if (test_thread_flag(TIF_SYSCALL_TRACE)) | 1532 | if (test_thread_flag(TIF_SYSCALL_TRACE)) |
| 1530 | tracehook_report_syscall_exit(regs, 0); | 1533 | tracehook_report_syscall_exit(regs, 0); |
diff --git a/include/trace/syscall.h b/include/trace/syscall.h index c55fcce4fbb2..3951d774de18 100644 --- a/include/trace/syscall.h +++ b/include/trace/syscall.h | |||
| @@ -1,8 +1,28 @@ | |||
| 1 | #ifndef _TRACE_SYSCALL_H | 1 | #ifndef _TRACE_SYSCALL_H |
| 2 | #define _TRACE_SYSCALL_H | 2 | #define _TRACE_SYSCALL_H |
| 3 | 3 | ||
| 4 | #include <linux/tracepoint.h> | ||
| 5 | |||
| 4 | #include <asm/ptrace.h> | 6 | #include <asm/ptrace.h> |
| 5 | 7 | ||
| 8 | |||
| 9 | extern void syscall_regfunc(void); | ||
| 10 | extern void syscall_unregfunc(void); | ||
| 11 | |||
| 12 | DECLARE_TRACE_WITH_CALLBACK(syscall_enter, | ||
| 13 | TP_PROTO(struct pt_regs *regs, long id), | ||
| 14 | TP_ARGS(regs, id), | ||
| 15 | syscall_regfunc, | ||
| 16 | syscall_unregfunc | ||
| 17 | ); | ||
| 18 | |||
| 19 | DECLARE_TRACE_WITH_CALLBACK(syscall_exit, | ||
| 20 | TP_PROTO(struct pt_regs *regs, long ret), | ||
| 21 | TP_ARGS(regs, ret), | ||
| 22 | syscall_regfunc, | ||
| 23 | syscall_unregfunc | ||
| 24 | ); | ||
| 25 | |||
| 6 | /* | 26 | /* |
| 7 | * A syscall entry in the ftrace syscalls array. | 27 | * A syscall entry in the ftrace syscalls array. |
| 8 | * | 28 | * |
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c index 1ef5d3a601c7..070a42bb8920 100644 --- a/kernel/tracepoint.c +++ b/kernel/tracepoint.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/tracepoint.h> | 24 | #include <linux/tracepoint.h> |
| 25 | #include <linux/err.h> | 25 | #include <linux/err.h> |
| 26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
| 27 | #include <linux/sched.h> | ||
| 27 | 28 | ||
| 28 | extern struct tracepoint __start___tracepoints[]; | 29 | extern struct tracepoint __start___tracepoints[]; |
| 29 | extern struct tracepoint __stop___tracepoints[]; | 30 | extern struct tracepoint __stop___tracepoints[]; |
| @@ -577,3 +578,40 @@ static int init_tracepoints(void) | |||
| 577 | __initcall(init_tracepoints); | 578 | __initcall(init_tracepoints); |
| 578 | 579 | ||
| 579 | #endif /* CONFIG_MODULES */ | 580 | #endif /* CONFIG_MODULES */ |
| 581 | |||
| 582 | static DEFINE_MUTEX(regfunc_mutex); | ||
| 583 | static int sys_tracepoint_refcount; | ||
| 584 | |||
| 585 | void syscall_regfunc(void) | ||
| 586 | { | ||
| 587 | unsigned long flags; | ||
| 588 | struct task_struct *g, *t; | ||
| 589 | |||
| 590 | mutex_lock(®func_mutex); | ||
| 591 | if (!sys_tracepoint_refcount) { | ||
| 592 | read_lock_irqsave(&tasklist_lock, flags); | ||
| 593 | do_each_thread(g, t) { | ||
| 594 | set_tsk_thread_flag(t, TIF_SYSCALL_FTRACE); | ||
| 595 | } while_each_thread(g, t); | ||
| 596 | read_unlock_irqrestore(&tasklist_lock, flags); | ||
| 597 | } | ||
| 598 | sys_tracepoint_refcount++; | ||
| 599 | mutex_unlock(®func_mutex); | ||
| 600 | } | ||
| 601 | |||
| 602 | void syscall_unregfunc(void) | ||
| 603 | { | ||
| 604 | unsigned long flags; | ||
| 605 | struct task_struct *g, *t; | ||
| 606 | |||
| 607 | mutex_lock(®func_mutex); | ||
| 608 | sys_tracepoint_refcount--; | ||
| 609 | if (!sys_tracepoint_refcount) { | ||
| 610 | read_lock_irqsave(&tasklist_lock, flags); | ||
| 611 | do_each_thread(g, t) { | ||
| 612 | clear_tsk_thread_flag(t, TIF_SYSCALL_FTRACE); | ||
| 613 | } while_each_thread(g, t); | ||
| 614 | read_unlock_irqrestore(&tasklist_lock, flags); | ||
| 615 | } | ||
| 616 | mutex_unlock(®func_mutex); | ||
| 617 | } | ||
