aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/s390/Kconfig2
-rw-r--r--arch/s390/defconfig2
-rw-r--r--arch/s390/include/asm/thread_info.h4
-rw-r--r--arch/s390/kernel/entry.S2
-rw-r--r--arch/s390/kernel/entry64.S2
-rw-r--r--arch/s390/kernel/ptrace.c12
-rw-r--r--arch/x86/Kconfig2
-rw-r--r--arch/x86/configs/i386_defconfig2
-rw-r--r--arch/x86/configs/x86_64_defconfig2
-rw-r--r--arch/x86/include/asm/thread_info.h13
-rw-r--r--arch/x86/kernel/ptrace.c16
-rw-r--r--include/linux/tracepoint.h46
-rw-r--r--include/trace/define_trace.h5
-rw-r--r--include/trace/events/syscalls.h70
-rw-r--r--include/trace/ftrace.h9
-rw-r--r--include/trace/syscall.h17
-rw-r--r--kernel/trace/Kconfig4
-rw-r--r--kernel/trace/trace_syscalls.c17
-rw-r--r--kernel/tracepoint.c20
19 files changed, 154 insertions, 93 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 2ae5d72f47ed..7238ef4c7a6b 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -84,7 +84,7 @@ config S390
84 select HAVE_FUNCTION_TRACER 84 select HAVE_FUNCTION_TRACER
85 select HAVE_FUNCTION_TRACE_MCOUNT_TEST 85 select HAVE_FUNCTION_TRACE_MCOUNT_TEST
86 select HAVE_FTRACE_MCOUNT_RECORD 86 select HAVE_FTRACE_MCOUNT_RECORD
87 select HAVE_FTRACE_SYSCALLS 87 select HAVE_SYSCALL_TRACEPOINTS
88 select HAVE_DYNAMIC_FTRACE 88 select HAVE_DYNAMIC_FTRACE
89 select HAVE_FUNCTION_GRAPH_TRACER 89 select HAVE_FUNCTION_GRAPH_TRACER
90 select HAVE_DEFAULT_NO_SPIN_MUTEXES 90 select HAVE_DEFAULT_NO_SPIN_MUTEXES
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index fcba206529f3..4e91a2573cc4 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -900,7 +900,7 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
900CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y 900CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
901CONFIG_HAVE_DYNAMIC_FTRACE=y 901CONFIG_HAVE_DYNAMIC_FTRACE=y
902CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y 902CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
903CONFIG_HAVE_FTRACE_SYSCALLS=y 903CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
904CONFIG_TRACING_SUPPORT=y 904CONFIG_TRACING_SUPPORT=y
905CONFIG_FTRACE=y 905CONFIG_FTRACE=y
906# CONFIG_FUNCTION_TRACER is not set 906# CONFIG_FUNCTION_TRACER is not set
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h
index ba1cab9fc1f9..07eb61b2fb3a 100644
--- a/arch/s390/include/asm/thread_info.h
+++ b/arch/s390/include/asm/thread_info.h
@@ -92,7 +92,7 @@ static inline struct thread_info *current_thread_info(void)
92#define TIF_SYSCALL_TRACE 8 /* syscall trace active */ 92#define TIF_SYSCALL_TRACE 8 /* syscall trace active */
93#define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */ 93#define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */
94#define TIF_SECCOMP 10 /* secure computing */ 94#define TIF_SECCOMP 10 /* secure computing */
95#define TIF_SYSCALL_FTRACE 11 /* ftrace syscall instrumentation */ 95#define TIF_SYSCALL_TRACEPOINT 11 /* syscall tracepoint instrumentation */
96#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ 96#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
97#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling 97#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling
98 TIF_NEED_RESCHED */ 98 TIF_NEED_RESCHED */
@@ -111,7 +111,7 @@ static inline struct thread_info *current_thread_info(void)
111#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) 111#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
112#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) 112#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
113#define _TIF_SECCOMP (1<<TIF_SECCOMP) 113#define _TIF_SECCOMP (1<<TIF_SECCOMP)
114#define _TIF_SYSCALL_FTRACE (1<<TIF_SYSCALL_FTRACE) 114#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
115#define _TIF_USEDFPU (1<<TIF_USEDFPU) 115#define _TIF_USEDFPU (1<<TIF_USEDFPU)
116#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) 116#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
117#define _TIF_31BIT (1<<TIF_31BIT) 117#define _TIF_31BIT (1<<TIF_31BIT)
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index c4c80a22bc1f..5d40fce878a5 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -54,7 +54,7 @@ _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
54_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ 54_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
55 _TIF_MCCK_PENDING) 55 _TIF_MCCK_PENDING)
56_TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ 56_TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
57 _TIF_SECCOMP>>8 | _TIF_SYSCALL_FTRACE>>8) 57 _TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8)
58 58
59STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER 59STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
60STACK_SIZE = 1 << STACK_SHIFT 60STACK_SIZE = 1 << STACK_SHIFT
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index f6618e9e15ef..3ceb53c9c493 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -57,7 +57,7 @@ _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
57_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ 57_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
58 _TIF_MCCK_PENDING) 58 _TIF_MCCK_PENDING)
59_TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ 59_TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
60 _TIF_SECCOMP>>8 | _TIF_SYSCALL_FTRACE>>8) 60 _TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8)
61 61
62#define BASED(name) name-system_call(%r13) 62#define BASED(name) name-system_call(%r13)
63 63
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index c5e87d891ca0..f3ddd7ac06c5 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -51,8 +51,8 @@
51#include "compat_ptrace.h" 51#include "compat_ptrace.h"
52#endif 52#endif
53 53
54DEFINE_TRACE(syscall_enter); 54#define CREATE_TRACE_POINTS
55DEFINE_TRACE(syscall_exit); 55#include <trace/events/syscalls.h>
56 56
57enum s390_regset { 57enum s390_regset {
58 REGSET_GENERAL, 58 REGSET_GENERAL,
@@ -664,8 +664,8 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
664 ret = -1; 664 ret = -1;
665 } 665 }
666 666
667 if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) 667 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
668 trace_syscall_enter(regs, regs->gprs[2]); 668 trace_sys_enter(regs, regs->gprs[2]);
669 669
670 if (unlikely(current->audit_context)) 670 if (unlikely(current->audit_context))
671 audit_syscall_entry(is_compat_task() ? 671 audit_syscall_entry(is_compat_task() ?
@@ -682,8 +682,8 @@ asmlinkage void do_syscall_trace_exit(struct pt_regs *regs)
682 audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]), 682 audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]),
683 regs->gprs[2]); 683 regs->gprs[2]);
684 684
685 if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) 685 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
686 trace_syscall_exit(regs, regs->gprs[2]); 686 trace_sys_exit(regs, regs->gprs[2]);
687 687
688 if (test_thread_flag(TIF_SYSCALL_TRACE)) 688 if (test_thread_flag(TIF_SYSCALL_TRACE))
689 tracehook_report_syscall_exit(regs, 0); 689 tracehook_report_syscall_exit(regs, 0);
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 738bdc6b0f8b..d59cbf758f34 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -37,7 +37,7 @@ config X86
37 select HAVE_FUNCTION_GRAPH_FP_TEST 37 select HAVE_FUNCTION_GRAPH_FP_TEST
38 select HAVE_FUNCTION_TRACE_MCOUNT_TEST 38 select HAVE_FUNCTION_TRACE_MCOUNT_TEST
39 select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE 39 select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE
40 select HAVE_FTRACE_SYSCALLS 40 select HAVE_SYSCALL_TRACEPOINTS
41 select HAVE_KVM 41 select HAVE_KVM
42 select HAVE_ARCH_KGDB 42 select HAVE_ARCH_KGDB
43 select HAVE_ARCH_TRACEHOOK 43 select HAVE_ARCH_TRACEHOOK
diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig
index edb992ebef92..d28fad19654a 100644
--- a/arch/x86/configs/i386_defconfig
+++ b/arch/x86/configs/i386_defconfig
@@ -2355,7 +2355,7 @@ CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
2355CONFIG_HAVE_DYNAMIC_FTRACE=y 2355CONFIG_HAVE_DYNAMIC_FTRACE=y
2356CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y 2356CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
2357CONFIG_HAVE_HW_BRANCH_TRACER=y 2357CONFIG_HAVE_HW_BRANCH_TRACER=y
2358CONFIG_HAVE_FTRACE_SYSCALLS=y 2358CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
2359CONFIG_RING_BUFFER=y 2359CONFIG_RING_BUFFER=y
2360CONFIG_TRACING=y 2360CONFIG_TRACING=y
2361CONFIG_TRACING_SUPPORT=y 2361CONFIG_TRACING_SUPPORT=y
diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig
index cee1dd2e69b2..6c86acd847a4 100644
--- a/arch/x86/configs/x86_64_defconfig
+++ b/arch/x86/configs/x86_64_defconfig
@@ -2329,7 +2329,7 @@ CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
2329CONFIG_HAVE_DYNAMIC_FTRACE=y 2329CONFIG_HAVE_DYNAMIC_FTRACE=y
2330CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y 2330CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
2331CONFIG_HAVE_HW_BRANCH_TRACER=y 2331CONFIG_HAVE_HW_BRANCH_TRACER=y
2332CONFIG_HAVE_FTRACE_SYSCALLS=y 2332CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
2333CONFIG_RING_BUFFER=y 2333CONFIG_RING_BUFFER=y
2334CONFIG_TRACING=y 2334CONFIG_TRACING=y
2335CONFIG_TRACING_SUPPORT=y 2335CONFIG_TRACING_SUPPORT=y
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index fad7d40b75f8..6f7786aea4fc 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -95,7 +95,7 @@ struct thread_info {
95#define TIF_DEBUGCTLMSR 25 /* uses thread_struct.debugctlmsr */ 95#define TIF_DEBUGCTLMSR 25 /* uses thread_struct.debugctlmsr */
96#define TIF_DS_AREA_MSR 26 /* uses thread_struct.ds_area_msr */ 96#define TIF_DS_AREA_MSR 26 /* uses thread_struct.ds_area_msr */
97#define TIF_LAZY_MMU_UPDATES 27 /* task is updating the mmu lazily */ 97#define TIF_LAZY_MMU_UPDATES 27 /* task is updating the mmu lazily */
98#define TIF_SYSCALL_FTRACE 28 /* for ftrace syscall instrumentation */ 98#define TIF_SYSCALL_TRACEPOINT 28 /* syscall tracepoint instrumentation */
99 99
100#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) 100#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
101#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) 101#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
@@ -118,17 +118,17 @@ struct thread_info {
118#define _TIF_DEBUGCTLMSR (1 << TIF_DEBUGCTLMSR) 118#define _TIF_DEBUGCTLMSR (1 << TIF_DEBUGCTLMSR)
119#define _TIF_DS_AREA_MSR (1 << TIF_DS_AREA_MSR) 119#define _TIF_DS_AREA_MSR (1 << TIF_DS_AREA_MSR)
120#define _TIF_LAZY_MMU_UPDATES (1 << TIF_LAZY_MMU_UPDATES) 120#define _TIF_LAZY_MMU_UPDATES (1 << TIF_LAZY_MMU_UPDATES)
121#define _TIF_SYSCALL_FTRACE (1 << TIF_SYSCALL_FTRACE) 121#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
122 122
123/* work to do in syscall_trace_enter() */ 123/* work to do in syscall_trace_enter() */
124#define _TIF_WORK_SYSCALL_ENTRY \ 124#define _TIF_WORK_SYSCALL_ENTRY \
125 (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | _TIF_SYSCALL_FTRACE | \ 125 (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | _TIF_SYSCALL_AUDIT | \
126 _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | _TIF_SINGLESTEP) 126 _TIF_SECCOMP | _TIF_SINGLESTEP | _TIF_SYSCALL_TRACEPOINT)
127 127
128/* work to do in syscall_trace_leave() */ 128/* work to do in syscall_trace_leave() */
129#define _TIF_WORK_SYSCALL_EXIT \ 129#define _TIF_WORK_SYSCALL_EXIT \
130 (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP | \ 130 (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP | \
131 _TIF_SYSCALL_FTRACE) 131 _TIF_SYSCALL_TRACEPOINT)
132 132
133/* work to do on interrupt/exception return */ 133/* work to do on interrupt/exception return */
134#define _TIF_WORK_MASK \ 134#define _TIF_WORK_MASK \
@@ -137,7 +137,8 @@ struct thread_info {
137 _TIF_SINGLESTEP|_TIF_SECCOMP|_TIF_SYSCALL_EMU)) 137 _TIF_SINGLESTEP|_TIF_SECCOMP|_TIF_SYSCALL_EMU))
138 138
139/* work to do on any return to user space */ 139/* work to do on any return to user space */
140#define _TIF_ALLWORK_MASK ((0x0000FFFF & ~_TIF_SECCOMP) | _TIF_SYSCALL_FTRACE) 140#define _TIF_ALLWORK_MASK \
141 ((0x0000FFFF & ~_TIF_SECCOMP) | _TIF_SYSCALL_TRACEPOINT)
141 142
142/* Only used for 64 bit */ 143/* Only used for 64 bit */
143#define _TIF_DO_NOTIFY_MASK \ 144#define _TIF_DO_NOTIFY_MASK \
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 34dd6f15185d..8d7d5c9c1be3 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -35,13 +35,11 @@
35#include <asm/proto.h> 35#include <asm/proto.h>
36#include <asm/ds.h> 36#include <asm/ds.h>
37 37
38#include <trace/syscall.h>
39
40DEFINE_TRACE(syscall_enter);
41DEFINE_TRACE(syscall_exit);
42
43#include "tls.h" 38#include "tls.h"
44 39
40#define CREATE_TRACE_POINTS
41#include <trace/events/syscalls.h>
42
45enum x86_regset { 43enum x86_regset {
46 REGSET_GENERAL, 44 REGSET_GENERAL,
47 REGSET_FP, 45 REGSET_FP,
@@ -1500,8 +1498,8 @@ asmregparm long syscall_trace_enter(struct pt_regs *regs)
1500 tracehook_report_syscall_entry(regs)) 1498 tracehook_report_syscall_entry(regs))
1501 ret = -1L; 1499 ret = -1L;
1502 1500
1503 if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) 1501 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
1504 trace_syscall_enter(regs, regs->orig_ax); 1502 trace_sys_enter(regs, regs->orig_ax);
1505 1503
1506 if (unlikely(current->audit_context)) { 1504 if (unlikely(current->audit_context)) {
1507 if (IS_IA32) 1505 if (IS_IA32)
@@ -1526,8 +1524,8 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs)
1526 if (unlikely(current->audit_context)) 1524 if (unlikely(current->audit_context))
1527 audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax); 1525 audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax);
1528 1526
1529 if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) 1527 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
1530 trace_syscall_exit(regs, regs->ax); 1528 trace_sys_exit(regs, regs->ax);
1531 1529
1532 if (test_thread_flag(TIF_SYSCALL_TRACE)) 1530 if (test_thread_flag(TIF_SYSCALL_TRACE))
1533 tracehook_report_syscall_exit(regs, 0); 1531 tracehook_report_syscall_exit(regs, 0);
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index 0341f2e2698a..63a3f7a80580 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -23,6 +23,8 @@ struct tracepoint;
23struct tracepoint { 23struct tracepoint {
24 const char *name; /* Tracepoint name */ 24 const char *name; /* Tracepoint name */
25 int state; /* State. */ 25 int state; /* State. */
26 void (*regfunc)(void);
27 void (*unregfunc)(void);
26 void **funcs; 28 void **funcs;
27} __attribute__((aligned(32))); /* 29} __attribute__((aligned(32))); /*
28 * Aligned on 32 bytes because it is 30 * Aligned on 32 bytes because it is
@@ -60,10 +62,8 @@ struct tracepoint {
60 * Make sure the alignment of the structure in the __tracepoints section will 62 * Make sure the alignment of the structure in the __tracepoints section will
61 * not add unwanted padding between the beginning of the section and the 63 * not add unwanted padding between the beginning of the section and the
62 * structure. Force alignment to the same alignment as the section start. 64 * structure. Force alignment to the same alignment as the section start.
63 * An optional set of (un)registration functions can be passed to perform any
64 * additional (un)registration work.
65 */ 65 */
66#define DECLARE_TRACE_WITH_CALLBACK(name, proto, args, reg, unreg) \ 66#define DECLARE_TRACE(name, proto, args) \
67 extern struct tracepoint __tracepoint_##name; \ 67 extern struct tracepoint __tracepoint_##name; \
68 static inline void trace_##name(proto) \ 68 static inline void trace_##name(proto) \
69 { \ 69 { \
@@ -73,36 +73,23 @@ struct tracepoint {
73 } \ 73 } \
74 static inline int register_trace_##name(void (*probe)(proto)) \ 74 static inline int register_trace_##name(void (*probe)(proto)) \
75 { \ 75 { \
76 int ret; \ 76 return tracepoint_probe_register(#name, (void *)probe); \
77 void (*func)(void) = reg; \
78 \
79 ret = tracepoint_probe_register(#name, (void *)probe); \
80 if (func && !ret) \
81 func(); \
82 return ret; \
83 } \ 77 } \
84 static inline int unregister_trace_##name(void (*probe)(proto)) \ 78 static inline int unregister_trace_##name(void (*probe)(proto)) \
85 { \ 79 { \
86 int ret; \ 80 return tracepoint_probe_unregister(#name, (void *)probe);\
87 void (*func)(void) = unreg; \
88 \
89 ret = tracepoint_probe_unregister(#name, (void *)probe);\
90 if (func && !ret) \
91 func(); \
92 return ret; \
93 } 81 }
94 82
95 83
96#define DECLARE_TRACE(name, proto, args) \ 84#define DEFINE_TRACE_FN(name, reg, unreg) \
97 DECLARE_TRACE_WITH_CALLBACK(name, TP_PROTO(proto), TP_ARGS(args),\
98 NULL, NULL);
99
100#define DEFINE_TRACE(name) \
101 static const char __tpstrtab_##name[] \ 85 static const char __tpstrtab_##name[] \
102 __attribute__((section("__tracepoints_strings"))) = #name; \ 86 __attribute__((section("__tracepoints_strings"))) = #name; \
103 struct tracepoint __tracepoint_##name \ 87 struct tracepoint __tracepoint_##name \
104 __attribute__((section("__tracepoints"), aligned(32))) = \ 88 __attribute__((section("__tracepoints"), aligned(32))) = \
105 { __tpstrtab_##name, 0, NULL } 89 { __tpstrtab_##name, 0, reg, unreg, NULL }
90
91#define DEFINE_TRACE(name) \
92 DEFINE_TRACE_FN(name, NULL, NULL);
106 93
107#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \ 94#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \
108 EXPORT_SYMBOL_GPL(__tracepoint_##name) 95 EXPORT_SYMBOL_GPL(__tracepoint_##name)
@@ -113,7 +100,7 @@ extern void tracepoint_update_probe_range(struct tracepoint *begin,
113 struct tracepoint *end); 100 struct tracepoint *end);
114 101
115#else /* !CONFIG_TRACEPOINTS */ 102#else /* !CONFIG_TRACEPOINTS */
116#define DECLARE_TRACE_WITH_CALLBACK(name, proto, args, reg, unreg) \ 103#define DECLARE_TRACE(name, proto, args) \
117 static inline void _do_trace_##name(struct tracepoint *tp, proto) \ 104 static inline void _do_trace_##name(struct tracepoint *tp, proto) \
118 { } \ 105 { } \
119 static inline void trace_##name(proto) \ 106 static inline void trace_##name(proto) \
@@ -127,10 +114,7 @@ extern void tracepoint_update_probe_range(struct tracepoint *begin,
127 return -ENOSYS; \ 114 return -ENOSYS; \
128 } 115 }
129 116
130#define DECLARE_TRACE(name, proto, args) \ 117#define DEFINE_TRACE_FN(name, reg, unreg)
131 DECLARE_TRACE_WITH_CALLBACK(name, TP_PROTO(proto), TP_ARGS(args),\
132 NULL, NULL);
133
134#define DEFINE_TRACE(name) 118#define DEFINE_TRACE(name)
135#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) 119#define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
136#define EXPORT_TRACEPOINT_SYMBOL(name) 120#define EXPORT_TRACEPOINT_SYMBOL(name)
@@ -291,9 +275,15 @@ static inline void tracepoint_synchronize_unregister(void)
291 * can also by used by generic instrumentation like SystemTap), and 275 * can also by used by generic instrumentation like SystemTap), and
292 * it is also used to expose a structured trace record in 276 * it is also used to expose a structured trace record in
293 * /sys/kernel/debug/tracing/events/. 277 * /sys/kernel/debug/tracing/events/.
278 *
279 * A set of (un)registration functions can be passed to the variant
280 * TRACE_EVENT_FN to perform any (un)registration work.
294 */ 281 */
295 282
296#define TRACE_EVENT(name, proto, args, struct, assign, print) \ 283#define TRACE_EVENT(name, proto, args, struct, assign, print) \
297 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) 284 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
285#define TRACE_EVENT_FN(name, proto, args, struct, \
286 assign, print, reg, unreg) \
287 DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
298 288
299#endif /* ifdef TRACE_EVENT (see note above) */ 289#endif /* ifdef TRACE_EVENT (see note above) */
diff --git a/include/trace/define_trace.h b/include/trace/define_trace.h
index cd150b9d8e32..a89ed590597a 100644
--- a/include/trace/define_trace.h
+++ b/include/trace/define_trace.h
@@ -26,6 +26,11 @@
26#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \ 26#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \
27 DEFINE_TRACE(name) 27 DEFINE_TRACE(name)
28 28
29#undef TRACE_EVENT_FN
30#define TRACE_EVENT_FN(name, proto, args, tstruct, \
31 assign, print, reg, unreg) \
32 DEFINE_TRACE_FN(name, reg, unreg)
33
29#undef DECLARE_TRACE 34#undef DECLARE_TRACE
30#define DECLARE_TRACE(name, proto, args) \ 35#define DECLARE_TRACE(name, proto, args) \
31 DEFINE_TRACE(name) 36 DEFINE_TRACE(name)
diff --git a/include/trace/events/syscalls.h b/include/trace/events/syscalls.h
new file mode 100644
index 000000000000..397dff2dbd5a
--- /dev/null
+++ b/include/trace/events/syscalls.h
@@ -0,0 +1,70 @@
1#undef TRACE_SYSTEM
2#define TRACE_SYSTEM syscalls
3
4#if !defined(_TRACE_EVENTS_SYSCALLS_H) || defined(TRACE_HEADER_MULTI_READ)
5#define _TRACE_EVENTS_SYSCALLS_H
6
7#include <linux/tracepoint.h>
8
9#include <asm/ptrace.h>
10#include <asm/syscall.h>
11
12
13#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
14
15extern void syscall_regfunc(void);
16extern void syscall_unregfunc(void);
17
18TRACE_EVENT_FN(sys_enter,
19
20 TP_PROTO(struct pt_regs *regs, long id),
21
22 TP_ARGS(regs, id),
23
24 TP_STRUCT__entry(
25 __field( long, id )
26 __array( unsigned long, args, 6 )
27 ),
28
29 TP_fast_assign(
30 __entry->id = id;
31 syscall_get_arguments(current, regs, 0, 6, __entry->args);
32 ),
33
34 TP_printk("NR %ld (%lx, %lx, %lx, %lx, %lx, %lx)",
35 __entry->id,
36 __entry->args[0], __entry->args[1], __entry->args[2],
37 __entry->args[3], __entry->args[4], __entry->args[5]),
38
39 syscall_regfunc, syscall_unregfunc
40);
41
42TRACE_EVENT_FN(sys_exit,
43
44 TP_PROTO(struct pt_regs *regs, long ret),
45
46 TP_ARGS(regs, ret),
47
48 TP_STRUCT__entry(
49 __field( long, id )
50 __field( long, ret )
51 ),
52
53 TP_fast_assign(
54 __entry->id = syscall_get_nr(current, regs);
55 __entry->ret = ret;
56 ),
57
58 TP_printk("NR %ld = %ld",
59 __entry->id, __entry->ret),
60
61 syscall_regfunc, syscall_unregfunc
62);
63
64#endif /* CONFIG_HAVE_SYSCALL_TRACEPOINTS */
65
66#endif /* _TRACE_EVENTS_SYSCALLS_H */
67
68/* This part must be outside protection */
69#include <trace/define_trace.h>
70
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index 1b1f742a6045..360a77ad79e1 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -45,6 +45,15 @@
45 }; \ 45 }; \
46 static struct ftrace_event_call event_##name 46 static struct ftrace_event_call event_##name
47 47
48/* Callbacks are meaningless to ftrace. */
49#undef TRACE_EVENT_FN
50#define TRACE_EVENT_FN(name, proto, args, tstruct, \
51 assign, print, reg, unreg) \
52 TRACE_EVENT(name, TP_PROTO(proto), TP_ARGS(args), \
53 TP_STRUCT__entry(tstruct), \
54 TP_fast_assign(assign), \
55 TP_printk(print))
56
48#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) 57#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
49 58
50 59
diff --git a/include/trace/syscall.h b/include/trace/syscall.h
index 9661dd406b93..5dc283ba5ae0 100644
--- a/include/trace/syscall.h
+++ b/include/trace/syscall.h
@@ -8,23 +8,6 @@
8#include <asm/ptrace.h> 8#include <asm/ptrace.h>
9 9
10 10
11extern void syscall_regfunc(void);
12extern void syscall_unregfunc(void);
13
14DECLARE_TRACE_WITH_CALLBACK(syscall_enter,
15 TP_PROTO(struct pt_regs *regs, long id),
16 TP_ARGS(regs, id),
17 syscall_regfunc,
18 syscall_unregfunc
19);
20
21DECLARE_TRACE_WITH_CALLBACK(syscall_exit,
22 TP_PROTO(struct pt_regs *regs, long ret),
23 TP_ARGS(regs, ret),
24 syscall_regfunc,
25 syscall_unregfunc
26);
27
28/* 11/*
29 * A syscall entry in the ftrace syscalls array. 12 * A syscall entry in the ftrace syscalls array.
30 * 13 *
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 019f380fd764..06be85a7ef8c 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -41,7 +41,7 @@ config HAVE_FTRACE_MCOUNT_RECORD
41config HAVE_HW_BRANCH_TRACER 41config HAVE_HW_BRANCH_TRACER
42 bool 42 bool
43 43
44config HAVE_FTRACE_SYSCALLS 44config HAVE_SYSCALL_TRACEPOINTS
45 bool 45 bool
46 46
47config TRACER_MAX_TRACE 47config TRACER_MAX_TRACE
@@ -211,7 +211,7 @@ config ENABLE_DEFAULT_TRACERS
211 211
212config FTRACE_SYSCALLS 212config FTRACE_SYSCALLS
213 bool "Trace syscalls" 213 bool "Trace syscalls"
214 depends on HAVE_FTRACE_SYSCALLS 214 depends on HAVE_SYSCALL_TRACEPOINTS
215 select GENERIC_TRACER 215 select GENERIC_TRACER
216 select KALLSYMS 216 select KALLSYMS
217 help 217 help
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index 97a2454760b0..85291c4de406 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -1,4 +1,5 @@
1#include <trace/syscall.h> 1#include <trace/syscall.h>
2#include <trace/events/syscalls.h>
2#include <linux/kernel.h> 3#include <linux/kernel.h>
3#include <linux/ftrace.h> 4#include <linux/ftrace.h>
4#include <linux/perf_counter.h> 5#include <linux/perf_counter.h>
@@ -288,7 +289,7 @@ int reg_event_syscall_enter(void *ptr)
288 return -ENOSYS; 289 return -ENOSYS;
289 mutex_lock(&syscall_trace_lock); 290 mutex_lock(&syscall_trace_lock);
290 if (!sys_refcount_enter) 291 if (!sys_refcount_enter)
291 ret = register_trace_syscall_enter(ftrace_syscall_enter); 292 ret = register_trace_sys_enter(ftrace_syscall_enter);
292 if (ret) { 293 if (ret) {
293 pr_info("event trace: Could not activate" 294 pr_info("event trace: Could not activate"
294 "syscall entry trace point"); 295 "syscall entry trace point");
@@ -313,7 +314,7 @@ void unreg_event_syscall_enter(void *ptr)
313 sys_refcount_enter--; 314 sys_refcount_enter--;
314 clear_bit(num, enabled_enter_syscalls); 315 clear_bit(num, enabled_enter_syscalls);
315 if (!sys_refcount_enter) 316 if (!sys_refcount_enter)
316 unregister_trace_syscall_enter(ftrace_syscall_enter); 317 unregister_trace_sys_enter(ftrace_syscall_enter);
317 mutex_unlock(&syscall_trace_lock); 318 mutex_unlock(&syscall_trace_lock);
318} 319}
319 320
@@ -329,7 +330,7 @@ int reg_event_syscall_exit(void *ptr)
329 return -ENOSYS; 330 return -ENOSYS;
330 mutex_lock(&syscall_trace_lock); 331 mutex_lock(&syscall_trace_lock);
331 if (!sys_refcount_exit) 332 if (!sys_refcount_exit)
332 ret = register_trace_syscall_exit(ftrace_syscall_exit); 333 ret = register_trace_sys_exit(ftrace_syscall_exit);
333 if (ret) { 334 if (ret) {
334 pr_info("event trace: Could not activate" 335 pr_info("event trace: Could not activate"
335 "syscall exit trace point"); 336 "syscall exit trace point");
@@ -354,7 +355,7 @@ void unreg_event_syscall_exit(void *ptr)
354 sys_refcount_exit--; 355 sys_refcount_exit--;
355 clear_bit(num, enabled_exit_syscalls); 356 clear_bit(num, enabled_exit_syscalls);
356 if (!sys_refcount_exit) 357 if (!sys_refcount_exit)
357 unregister_trace_syscall_exit(ftrace_syscall_exit); 358 unregister_trace_sys_exit(ftrace_syscall_exit);
358 mutex_unlock(&syscall_trace_lock); 359 mutex_unlock(&syscall_trace_lock);
359} 360}
360 361
@@ -420,7 +421,7 @@ int reg_prof_syscall_enter(char *name)
420 421
421 mutex_lock(&syscall_trace_lock); 422 mutex_lock(&syscall_trace_lock);
422 if (!sys_prof_refcount_enter) 423 if (!sys_prof_refcount_enter)
423 ret = register_trace_syscall_enter(prof_syscall_enter); 424 ret = register_trace_sys_enter(prof_syscall_enter);
424 if (ret) { 425 if (ret) {
425 pr_info("event trace: Could not activate" 426 pr_info("event trace: Could not activate"
426 "syscall entry trace point"); 427 "syscall entry trace point");
@@ -444,7 +445,7 @@ void unreg_prof_syscall_enter(char *name)
444 sys_prof_refcount_enter--; 445 sys_prof_refcount_enter--;
445 clear_bit(num, enabled_prof_enter_syscalls); 446 clear_bit(num, enabled_prof_enter_syscalls);
446 if (!sys_prof_refcount_enter) 447 if (!sys_prof_refcount_enter)
447 unregister_trace_syscall_enter(prof_syscall_enter); 448 unregister_trace_sys_enter(prof_syscall_enter);
448 mutex_unlock(&syscall_trace_lock); 449 mutex_unlock(&syscall_trace_lock);
449} 450}
450 451
@@ -481,7 +482,7 @@ int reg_prof_syscall_exit(char *name)
481 482
482 mutex_lock(&syscall_trace_lock); 483 mutex_lock(&syscall_trace_lock);
483 if (!sys_prof_refcount_exit) 484 if (!sys_prof_refcount_exit)
484 ret = register_trace_syscall_exit(prof_syscall_exit); 485 ret = register_trace_sys_exit(prof_syscall_exit);
485 if (ret) { 486 if (ret) {
486 pr_info("event trace: Could not activate" 487 pr_info("event trace: Could not activate"
487 "syscall entry trace point"); 488 "syscall entry trace point");
@@ -505,7 +506,7 @@ void unreg_prof_syscall_exit(char *name)
505 sys_prof_refcount_exit--; 506 sys_prof_refcount_exit--;
506 clear_bit(num, enabled_prof_exit_syscalls); 507 clear_bit(num, enabled_prof_exit_syscalls);
507 if (!sys_prof_refcount_exit) 508 if (!sys_prof_refcount_exit)
508 unregister_trace_syscall_exit(prof_syscall_exit); 509 unregister_trace_sys_exit(prof_syscall_exit);
509 mutex_unlock(&syscall_trace_lock); 510 mutex_unlock(&syscall_trace_lock);
510} 511}
511 512
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
index 06f165a44083..1a6a453b7efb 100644
--- a/kernel/tracepoint.c
+++ b/kernel/tracepoint.c
@@ -243,6 +243,11 @@ static void set_tracepoint(struct tracepoint_entry **entry,
243{ 243{
244 WARN_ON(strcmp((*entry)->name, elem->name) != 0); 244 WARN_ON(strcmp((*entry)->name, elem->name) != 0);
245 245
246 if (elem->regfunc && !elem->state && active)
247 elem->regfunc();
248 else if (elem->unregfunc && elem->state && !active)
249 elem->unregfunc();
250
246 /* 251 /*
247 * rcu_assign_pointer has a smp_wmb() which makes sure that the new 252 * rcu_assign_pointer has a smp_wmb() which makes sure that the new
248 * probe callbacks array is consistent before setting a pointer to it. 253 * probe callbacks array is consistent before setting a pointer to it.
@@ -262,6 +267,9 @@ static void set_tracepoint(struct tracepoint_entry **entry,
262 */ 267 */
263static void disable_tracepoint(struct tracepoint *elem) 268static void disable_tracepoint(struct tracepoint *elem)
264{ 269{
270 if (elem->unregfunc && elem->state)
271 elem->unregfunc();
272
265 elem->state = 0; 273 elem->state = 0;
266 rcu_assign_pointer(elem->funcs, NULL); 274 rcu_assign_pointer(elem->funcs, NULL);
267} 275}
@@ -576,9 +584,9 @@ __initcall(init_tracepoints);
576 584
577#endif /* CONFIG_MODULES */ 585#endif /* CONFIG_MODULES */
578 586
579#ifdef CONFIG_FTRACE_SYSCALLS 587#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
580 588
581static DEFINE_MUTEX(regfunc_mutex); 589/* NB: reg/unreg are called while guarded with the tracepoints_mutex */
582static int sys_tracepoint_refcount; 590static int sys_tracepoint_refcount;
583 591
584void syscall_regfunc(void) 592void syscall_regfunc(void)
@@ -586,16 +594,14 @@ void syscall_regfunc(void)
586 unsigned long flags; 594 unsigned long flags;
587 struct task_struct *g, *t; 595 struct task_struct *g, *t;
588 596
589 mutex_lock(&regfunc_mutex);
590 if (!sys_tracepoint_refcount) { 597 if (!sys_tracepoint_refcount) {
591 read_lock_irqsave(&tasklist_lock, flags); 598 read_lock_irqsave(&tasklist_lock, flags);
592 do_each_thread(g, t) { 599 do_each_thread(g, t) {
593 set_tsk_thread_flag(t, TIF_SYSCALL_FTRACE); 600 set_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT);
594 } while_each_thread(g, t); 601 } while_each_thread(g, t);
595 read_unlock_irqrestore(&tasklist_lock, flags); 602 read_unlock_irqrestore(&tasklist_lock, flags);
596 } 603 }
597 sys_tracepoint_refcount++; 604 sys_tracepoint_refcount++;
598 mutex_unlock(&regfunc_mutex);
599} 605}
600 606
601void syscall_unregfunc(void) 607void syscall_unregfunc(void)
@@ -603,15 +609,13 @@ void syscall_unregfunc(void)
603 unsigned long flags; 609 unsigned long flags;
604 struct task_struct *g, *t; 610 struct task_struct *g, *t;
605 611
606 mutex_lock(&regfunc_mutex);
607 sys_tracepoint_refcount--; 612 sys_tracepoint_refcount--;
608 if (!sys_tracepoint_refcount) { 613 if (!sys_tracepoint_refcount) {
609 read_lock_irqsave(&tasklist_lock, flags); 614 read_lock_irqsave(&tasklist_lock, flags);
610 do_each_thread(g, t) { 615 do_each_thread(g, t) {
611 clear_tsk_thread_flag(t, TIF_SYSCALL_FTRACE); 616 clear_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT);
612 } while_each_thread(g, t); 617 } while_each_thread(g, t);
613 read_unlock_irqrestore(&tasklist_lock, flags); 618 read_unlock_irqrestore(&tasklist_lock, flags);
614 } 619 }
615 mutex_unlock(&regfunc_mutex);
616} 620}
617#endif 621#endif