diff options
author | Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> | 2014-04-17 04:18:28 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-04-24 04:26:39 -0400 |
commit | 3da0f18007e5b87b573cf6ae8c445d59e757d274 (patch) | |
tree | 937fdf45d658417c57675f4eaa6e1574a9664c23 /kernel | |
parent | 820aede0209a51549e8a014c8030e29229920e4e (diff) |
kprobes, ftrace: Use NOKPROBE_SYMBOL macro in ftrace
Use NOKPROBE_SYMBOL macro to protect functions from
kprobes instead of __kprobes annotation in ftrace.
This applies nokprobe_inline annotation for some cases,
because NOKPROBE_SYMBOL() will inhibit inlining by
referring the symbol address.
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Link: http://lkml.kernel.org/r/20140417081828.26341.55152.stgit@ltc230.yrl.intra.hitachi.co.jp
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/trace/trace_event_perf.c | 5 | ||||
-rw-r--r-- | kernel/trace/trace_kprobe.c | 66 | ||||
-rw-r--r-- | kernel/trace/trace_probe.c | 61 | ||||
-rw-r--r-- | kernel/trace/trace_probe.h | 15 |
4 files changed, 82 insertions, 65 deletions
diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c index c894614de14d..5d12bb407b44 100644 --- a/kernel/trace/trace_event_perf.c +++ b/kernel/trace/trace_event_perf.c | |||
@@ -248,8 +248,8 @@ void perf_trace_del(struct perf_event *p_event, int flags) | |||
248 | tp_event->class->reg(tp_event, TRACE_REG_PERF_DEL, p_event); | 248 | tp_event->class->reg(tp_event, TRACE_REG_PERF_DEL, p_event); |
249 | } | 249 | } |
250 | 250 | ||
251 | __kprobes void *perf_trace_buf_prepare(int size, unsigned short type, | 251 | void *perf_trace_buf_prepare(int size, unsigned short type, |
252 | struct pt_regs *regs, int *rctxp) | 252 | struct pt_regs *regs, int *rctxp) |
253 | { | 253 | { |
254 | struct trace_entry *entry; | 254 | struct trace_entry *entry; |
255 | unsigned long flags; | 255 | unsigned long flags; |
@@ -281,6 +281,7 @@ __kprobes void *perf_trace_buf_prepare(int size, unsigned short type, | |||
281 | return raw_data; | 281 | return raw_data; |
282 | } | 282 | } |
283 | EXPORT_SYMBOL_GPL(perf_trace_buf_prepare); | 283 | EXPORT_SYMBOL_GPL(perf_trace_buf_prepare); |
284 | NOKPROBE_SYMBOL(perf_trace_buf_prepare); | ||
284 | 285 | ||
285 | #ifdef CONFIG_FUNCTION_TRACER | 286 | #ifdef CONFIG_FUNCTION_TRACER |
286 | static void | 287 | static void |
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index aa5f0bfcdf7b..242e4ec97d94 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
@@ -40,27 +40,27 @@ struct trace_kprobe { | |||
40 | (sizeof(struct probe_arg) * (n))) | 40 | (sizeof(struct probe_arg) * (n))) |
41 | 41 | ||
42 | 42 | ||
43 | static __kprobes bool trace_kprobe_is_return(struct trace_kprobe *tk) | 43 | static nokprobe_inline bool trace_kprobe_is_return(struct trace_kprobe *tk) |
44 | { | 44 | { |
45 | return tk->rp.handler != NULL; | 45 | return tk->rp.handler != NULL; |
46 | } | 46 | } |
47 | 47 | ||
48 | static __kprobes const char *trace_kprobe_symbol(struct trace_kprobe *tk) | 48 | static nokprobe_inline const char *trace_kprobe_symbol(struct trace_kprobe *tk) |
49 | { | 49 | { |
50 | return tk->symbol ? tk->symbol : "unknown"; | 50 | return tk->symbol ? tk->symbol : "unknown"; |
51 | } | 51 | } |
52 | 52 | ||
53 | static __kprobes unsigned long trace_kprobe_offset(struct trace_kprobe *tk) | 53 | static nokprobe_inline unsigned long trace_kprobe_offset(struct trace_kprobe *tk) |
54 | { | 54 | { |
55 | return tk->rp.kp.offset; | 55 | return tk->rp.kp.offset; |
56 | } | 56 | } |
57 | 57 | ||
58 | static __kprobes bool trace_kprobe_has_gone(struct trace_kprobe *tk) | 58 | static nokprobe_inline bool trace_kprobe_has_gone(struct trace_kprobe *tk) |
59 | { | 59 | { |
60 | return !!(kprobe_gone(&tk->rp.kp)); | 60 | return !!(kprobe_gone(&tk->rp.kp)); |
61 | } | 61 | } |
62 | 62 | ||
63 | static __kprobes bool trace_kprobe_within_module(struct trace_kprobe *tk, | 63 | static nokprobe_inline bool trace_kprobe_within_module(struct trace_kprobe *tk, |
64 | struct module *mod) | 64 | struct module *mod) |
65 | { | 65 | { |
66 | int len = strlen(mod->name); | 66 | int len = strlen(mod->name); |
@@ -68,7 +68,7 @@ static __kprobes bool trace_kprobe_within_module(struct trace_kprobe *tk, | |||
68 | return strncmp(mod->name, name, len) == 0 && name[len] == ':'; | 68 | return strncmp(mod->name, name, len) == 0 && name[len] == ':'; |
69 | } | 69 | } |
70 | 70 | ||
71 | static __kprobes bool trace_kprobe_is_on_module(struct trace_kprobe *tk) | 71 | static nokprobe_inline bool trace_kprobe_is_on_module(struct trace_kprobe *tk) |
72 | { | 72 | { |
73 | return !!strchr(trace_kprobe_symbol(tk), ':'); | 73 | return !!strchr(trace_kprobe_symbol(tk), ':'); |
74 | } | 74 | } |
@@ -132,19 +132,21 @@ struct symbol_cache *alloc_symbol_cache(const char *sym, long offset) | |||
132 | * Kprobes-specific fetch functions | 132 | * Kprobes-specific fetch functions |
133 | */ | 133 | */ |
134 | #define DEFINE_FETCH_stack(type) \ | 134 | #define DEFINE_FETCH_stack(type) \ |
135 | static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\ | 135 | static void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs, \ |
136 | void *offset, void *dest) \ | 136 | void *offset, void *dest) \ |
137 | { \ | 137 | { \ |
138 | *(type *)dest = (type)regs_get_kernel_stack_nth(regs, \ | 138 | *(type *)dest = (type)regs_get_kernel_stack_nth(regs, \ |
139 | (unsigned int)((unsigned long)offset)); \ | 139 | (unsigned int)((unsigned long)offset)); \ |
140 | } | 140 | } \ |
141 | NOKPROBE_SYMBOL(FETCH_FUNC_NAME(stack, type)); | ||
142 | |||
141 | DEFINE_BASIC_FETCH_FUNCS(stack) | 143 | DEFINE_BASIC_FETCH_FUNCS(stack) |
142 | /* No string on the stack entry */ | 144 | /* No string on the stack entry */ |
143 | #define fetch_stack_string NULL | 145 | #define fetch_stack_string NULL |
144 | #define fetch_stack_string_size NULL | 146 | #define fetch_stack_string_size NULL |
145 | 147 | ||
146 | #define DEFINE_FETCH_memory(type) \ | 148 | #define DEFINE_FETCH_memory(type) \ |
147 | static __kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,\ | 149 | static void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs, \ |
148 | void *addr, void *dest) \ | 150 | void *addr, void *dest) \ |
149 | { \ | 151 | { \ |
150 | type retval; \ | 152 | type retval; \ |
@@ -152,14 +154,16 @@ static __kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,\ | |||
152 | *(type *)dest = 0; \ | 154 | *(type *)dest = 0; \ |
153 | else \ | 155 | else \ |
154 | *(type *)dest = retval; \ | 156 | *(type *)dest = retval; \ |
155 | } | 157 | } \ |
158 | NOKPROBE_SYMBOL(FETCH_FUNC_NAME(memory, type)); | ||
159 | |||
156 | DEFINE_BASIC_FETCH_FUNCS(memory) | 160 | DEFINE_BASIC_FETCH_FUNCS(memory) |
157 | /* | 161 | /* |
158 | * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max | 162 | * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max |
159 | * length and relative data location. | 163 | * length and relative data location. |
160 | */ | 164 | */ |
161 | static __kprobes void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs, | 165 | static void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs, |
162 | void *addr, void *dest) | 166 | void *addr, void *dest) |
163 | { | 167 | { |
164 | long ret; | 168 | long ret; |
165 | int maxlen = get_rloc_len(*(u32 *)dest); | 169 | int maxlen = get_rloc_len(*(u32 *)dest); |
@@ -193,10 +197,11 @@ static __kprobes void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs, | |||
193 | get_rloc_offs(*(u32 *)dest)); | 197 | get_rloc_offs(*(u32 *)dest)); |
194 | } | 198 | } |
195 | } | 199 | } |
200 | NOKPROBE_SYMBOL(FETCH_FUNC_NAME(memory, string)); | ||
196 | 201 | ||
197 | /* Return the length of string -- including null terminal byte */ | 202 | /* Return the length of string -- including null terminal byte */ |
198 | static __kprobes void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs, | 203 | static void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs, |
199 | void *addr, void *dest) | 204 | void *addr, void *dest) |
200 | { | 205 | { |
201 | mm_segment_t old_fs; | 206 | mm_segment_t old_fs; |
202 | int ret, len = 0; | 207 | int ret, len = 0; |
@@ -219,17 +224,19 @@ static __kprobes void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs, | |||
219 | else | 224 | else |
220 | *(u32 *)dest = len; | 225 | *(u32 *)dest = len; |
221 | } | 226 | } |
227 | NOKPROBE_SYMBOL(FETCH_FUNC_NAME(memory, string_size)); | ||
222 | 228 | ||
223 | #define DEFINE_FETCH_symbol(type) \ | 229 | #define DEFINE_FETCH_symbol(type) \ |
224 | __kprobes void FETCH_FUNC_NAME(symbol, type)(struct pt_regs *regs, \ | 230 | void FETCH_FUNC_NAME(symbol, type)(struct pt_regs *regs, void *data, void *dest)\ |
225 | void *data, void *dest) \ | ||
226 | { \ | 231 | { \ |
227 | struct symbol_cache *sc = data; \ | 232 | struct symbol_cache *sc = data; \ |
228 | if (sc->addr) \ | 233 | if (sc->addr) \ |
229 | fetch_memory_##type(regs, (void *)sc->addr, dest); \ | 234 | fetch_memory_##type(regs, (void *)sc->addr, dest); \ |
230 | else \ | 235 | else \ |
231 | *(type *)dest = 0; \ | 236 | *(type *)dest = 0; \ |
232 | } | 237 | } \ |
238 | NOKPROBE_SYMBOL(FETCH_FUNC_NAME(symbol, type)); | ||
239 | |||
233 | DEFINE_BASIC_FETCH_FUNCS(symbol) | 240 | DEFINE_BASIC_FETCH_FUNCS(symbol) |
234 | DEFINE_FETCH_symbol(string) | 241 | DEFINE_FETCH_symbol(string) |
235 | DEFINE_FETCH_symbol(string_size) | 242 | DEFINE_FETCH_symbol(string_size) |
@@ -907,7 +914,7 @@ static const struct file_operations kprobe_profile_ops = { | |||
907 | }; | 914 | }; |
908 | 915 | ||
909 | /* Kprobe handler */ | 916 | /* Kprobe handler */ |
910 | static __kprobes void | 917 | static nokprobe_inline void |
911 | __kprobe_trace_func(struct trace_kprobe *tk, struct pt_regs *regs, | 918 | __kprobe_trace_func(struct trace_kprobe *tk, struct pt_regs *regs, |
912 | struct ftrace_event_file *ftrace_file) | 919 | struct ftrace_event_file *ftrace_file) |
913 | { | 920 | { |
@@ -943,7 +950,7 @@ __kprobe_trace_func(struct trace_kprobe *tk, struct pt_regs *regs, | |||
943 | entry, irq_flags, pc, regs); | 950 | entry, irq_flags, pc, regs); |
944 | } | 951 | } |
945 | 952 | ||
946 | static __kprobes void | 953 | static void |
947 | kprobe_trace_func(struct trace_kprobe *tk, struct pt_regs *regs) | 954 | kprobe_trace_func(struct trace_kprobe *tk, struct pt_regs *regs) |
948 | { | 955 | { |
949 | struct event_file_link *link; | 956 | struct event_file_link *link; |
@@ -951,9 +958,10 @@ kprobe_trace_func(struct trace_kprobe *tk, struct pt_regs *regs) | |||
951 | list_for_each_entry_rcu(link, &tk->tp.files, list) | 958 | list_for_each_entry_rcu(link, &tk->tp.files, list) |
952 | __kprobe_trace_func(tk, regs, link->file); | 959 | __kprobe_trace_func(tk, regs, link->file); |
953 | } | 960 | } |
961 | NOKPROBE_SYMBOL(kprobe_trace_func); | ||
954 | 962 | ||
955 | /* Kretprobe handler */ | 963 | /* Kretprobe handler */ |
956 | static __kprobes void | 964 | static nokprobe_inline void |
957 | __kretprobe_trace_func(struct trace_kprobe *tk, struct kretprobe_instance *ri, | 965 | __kretprobe_trace_func(struct trace_kprobe *tk, struct kretprobe_instance *ri, |
958 | struct pt_regs *regs, | 966 | struct pt_regs *regs, |
959 | struct ftrace_event_file *ftrace_file) | 967 | struct ftrace_event_file *ftrace_file) |
@@ -991,7 +999,7 @@ __kretprobe_trace_func(struct trace_kprobe *tk, struct kretprobe_instance *ri, | |||
991 | entry, irq_flags, pc, regs); | 999 | entry, irq_flags, pc, regs); |
992 | } | 1000 | } |
993 | 1001 | ||
994 | static __kprobes void | 1002 | static void |
995 | kretprobe_trace_func(struct trace_kprobe *tk, struct kretprobe_instance *ri, | 1003 | kretprobe_trace_func(struct trace_kprobe *tk, struct kretprobe_instance *ri, |
996 | struct pt_regs *regs) | 1004 | struct pt_regs *regs) |
997 | { | 1005 | { |
@@ -1000,6 +1008,7 @@ kretprobe_trace_func(struct trace_kprobe *tk, struct kretprobe_instance *ri, | |||
1000 | list_for_each_entry_rcu(link, &tk->tp.files, list) | 1008 | list_for_each_entry_rcu(link, &tk->tp.files, list) |
1001 | __kretprobe_trace_func(tk, ri, regs, link->file); | 1009 | __kretprobe_trace_func(tk, ri, regs, link->file); |
1002 | } | 1010 | } |
1011 | NOKPROBE_SYMBOL(kretprobe_trace_func); | ||
1003 | 1012 | ||
1004 | /* Event entry printers */ | 1013 | /* Event entry printers */ |
1005 | static enum print_line_t | 1014 | static enum print_line_t |
@@ -1131,7 +1140,7 @@ static int kretprobe_event_define_fields(struct ftrace_event_call *event_call) | |||
1131 | #ifdef CONFIG_PERF_EVENTS | 1140 | #ifdef CONFIG_PERF_EVENTS |
1132 | 1141 | ||
1133 | /* Kprobe profile handler */ | 1142 | /* Kprobe profile handler */ |
1134 | static __kprobes void | 1143 | static void |
1135 | kprobe_perf_func(struct trace_kprobe *tk, struct pt_regs *regs) | 1144 | kprobe_perf_func(struct trace_kprobe *tk, struct pt_regs *regs) |
1136 | { | 1145 | { |
1137 | struct ftrace_event_call *call = &tk->tp.call; | 1146 | struct ftrace_event_call *call = &tk->tp.call; |
@@ -1158,9 +1167,10 @@ kprobe_perf_func(struct trace_kprobe *tk, struct pt_regs *regs) | |||
1158 | store_trace_args(sizeof(*entry), &tk->tp, regs, (u8 *)&entry[1], dsize); | 1167 | store_trace_args(sizeof(*entry), &tk->tp, regs, (u8 *)&entry[1], dsize); |
1159 | perf_trace_buf_submit(entry, size, rctx, 0, 1, regs, head, NULL); | 1168 | perf_trace_buf_submit(entry, size, rctx, 0, 1, regs, head, NULL); |
1160 | } | 1169 | } |
1170 | NOKPROBE_SYMBOL(kprobe_perf_func); | ||
1161 | 1171 | ||
1162 | /* Kretprobe profile handler */ | 1172 | /* Kretprobe profile handler */ |
1163 | static __kprobes void | 1173 | static void |
1164 | kretprobe_perf_func(struct trace_kprobe *tk, struct kretprobe_instance *ri, | 1174 | kretprobe_perf_func(struct trace_kprobe *tk, struct kretprobe_instance *ri, |
1165 | struct pt_regs *regs) | 1175 | struct pt_regs *regs) |
1166 | { | 1176 | { |
@@ -1188,6 +1198,7 @@ kretprobe_perf_func(struct trace_kprobe *tk, struct kretprobe_instance *ri, | |||
1188 | store_trace_args(sizeof(*entry), &tk->tp, regs, (u8 *)&entry[1], dsize); | 1198 | store_trace_args(sizeof(*entry), &tk->tp, regs, (u8 *)&entry[1], dsize); |
1189 | perf_trace_buf_submit(entry, size, rctx, 0, 1, regs, head, NULL); | 1199 | perf_trace_buf_submit(entry, size, rctx, 0, 1, regs, head, NULL); |
1190 | } | 1200 | } |
1201 | NOKPROBE_SYMBOL(kretprobe_perf_func); | ||
1191 | #endif /* CONFIG_PERF_EVENTS */ | 1202 | #endif /* CONFIG_PERF_EVENTS */ |
1192 | 1203 | ||
1193 | /* | 1204 | /* |
@@ -1223,8 +1234,7 @@ static int kprobe_register(struct ftrace_event_call *event, | |||
1223 | return 0; | 1234 | return 0; |
1224 | } | 1235 | } |
1225 | 1236 | ||
1226 | static __kprobes | 1237 | static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs) |
1227 | int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs) | ||
1228 | { | 1238 | { |
1229 | struct trace_kprobe *tk = container_of(kp, struct trace_kprobe, rp.kp); | 1239 | struct trace_kprobe *tk = container_of(kp, struct trace_kprobe, rp.kp); |
1230 | 1240 | ||
@@ -1238,9 +1248,10 @@ int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs) | |||
1238 | #endif | 1248 | #endif |
1239 | return 0; /* We don't tweek kernel, so just return 0 */ | 1249 | return 0; /* We don't tweek kernel, so just return 0 */ |
1240 | } | 1250 | } |
1251 | NOKPROBE_SYMBOL(kprobe_dispatcher); | ||
1241 | 1252 | ||
1242 | static __kprobes | 1253 | static int |
1243 | int kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs) | 1254 | kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs) |
1244 | { | 1255 | { |
1245 | struct trace_kprobe *tk = container_of(ri->rp, struct trace_kprobe, rp); | 1256 | struct trace_kprobe *tk = container_of(ri->rp, struct trace_kprobe, rp); |
1246 | 1257 | ||
@@ -1254,6 +1265,7 @@ int kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs) | |||
1254 | #endif | 1265 | #endif |
1255 | return 0; /* We don't tweek kernel, so just return 0 */ | 1266 | return 0; /* We don't tweek kernel, so just return 0 */ |
1256 | } | 1267 | } |
1268 | NOKPROBE_SYMBOL(kretprobe_dispatcher); | ||
1257 | 1269 | ||
1258 | static struct trace_event_functions kretprobe_funcs = { | 1270 | static struct trace_event_functions kretprobe_funcs = { |
1259 | .trace = print_kretprobe_event | 1271 | .trace = print_kretprobe_event |
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index d3a91e40a659..d4b9fc22cd27 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c | |||
@@ -37,13 +37,13 @@ const char *reserved_field_names[] = { | |||
37 | 37 | ||
38 | /* Printing in basic type function template */ | 38 | /* Printing in basic type function template */ |
39 | #define DEFINE_BASIC_PRINT_TYPE_FUNC(type, fmt) \ | 39 | #define DEFINE_BASIC_PRINT_TYPE_FUNC(type, fmt) \ |
40 | __kprobes int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s, \ | 40 | int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s, const char *name, \ |
41 | const char *name, \ | 41 | void *data, void *ent) \ |
42 | void *data, void *ent) \ | ||
43 | { \ | 42 | { \ |
44 | return trace_seq_printf(s, " %s=" fmt, name, *(type *)data); \ | 43 | return trace_seq_printf(s, " %s=" fmt, name, *(type *)data); \ |
45 | } \ | 44 | } \ |
46 | const char PRINT_TYPE_FMT_NAME(type)[] = fmt; | 45 | const char PRINT_TYPE_FMT_NAME(type)[] = fmt; \ |
46 | NOKPROBE_SYMBOL(PRINT_TYPE_FUNC_NAME(type)); | ||
47 | 47 | ||
48 | DEFINE_BASIC_PRINT_TYPE_FUNC(u8 , "0x%x") | 48 | DEFINE_BASIC_PRINT_TYPE_FUNC(u8 , "0x%x") |
49 | DEFINE_BASIC_PRINT_TYPE_FUNC(u16, "0x%x") | 49 | DEFINE_BASIC_PRINT_TYPE_FUNC(u16, "0x%x") |
@@ -55,9 +55,8 @@ DEFINE_BASIC_PRINT_TYPE_FUNC(s32, "%d") | |||
55 | DEFINE_BASIC_PRINT_TYPE_FUNC(s64, "%Ld") | 55 | DEFINE_BASIC_PRINT_TYPE_FUNC(s64, "%Ld") |
56 | 56 | ||
57 | /* Print type function for string type */ | 57 | /* Print type function for string type */ |
58 | __kprobes int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s, | 58 | int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s, const char *name, |
59 | const char *name, | 59 | void *data, void *ent) |
60 | void *data, void *ent) | ||
61 | { | 60 | { |
62 | int len = *(u32 *)data >> 16; | 61 | int len = *(u32 *)data >> 16; |
63 | 62 | ||
@@ -67,6 +66,7 @@ __kprobes int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s, | |||
67 | return trace_seq_printf(s, " %s=\"%s\"", name, | 66 | return trace_seq_printf(s, " %s=\"%s\"", name, |
68 | (const char *)get_loc_data(data, ent)); | 67 | (const char *)get_loc_data(data, ent)); |
69 | } | 68 | } |
69 | NOKPROBE_SYMBOL(PRINT_TYPE_FUNC_NAME(string)); | ||
70 | 70 | ||
71 | const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\""; | 71 | const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\""; |
72 | 72 | ||
@@ -81,23 +81,24 @@ const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\""; | |||
81 | 81 | ||
82 | /* Data fetch function templates */ | 82 | /* Data fetch function templates */ |
83 | #define DEFINE_FETCH_reg(type) \ | 83 | #define DEFINE_FETCH_reg(type) \ |
84 | __kprobes void FETCH_FUNC_NAME(reg, type)(struct pt_regs *regs, \ | 84 | void FETCH_FUNC_NAME(reg, type)(struct pt_regs *regs, void *offset, void *dest) \ |
85 | void *offset, void *dest) \ | ||
86 | { \ | 85 | { \ |
87 | *(type *)dest = (type)regs_get_register(regs, \ | 86 | *(type *)dest = (type)regs_get_register(regs, \ |
88 | (unsigned int)((unsigned long)offset)); \ | 87 | (unsigned int)((unsigned long)offset)); \ |
89 | } | 88 | } \ |
89 | NOKPROBE_SYMBOL(FETCH_FUNC_NAME(reg, type)); | ||
90 | DEFINE_BASIC_FETCH_FUNCS(reg) | 90 | DEFINE_BASIC_FETCH_FUNCS(reg) |
91 | /* No string on the register */ | 91 | /* No string on the register */ |
92 | #define fetch_reg_string NULL | 92 | #define fetch_reg_string NULL |
93 | #define fetch_reg_string_size NULL | 93 | #define fetch_reg_string_size NULL |
94 | 94 | ||
95 | #define DEFINE_FETCH_retval(type) \ | 95 | #define DEFINE_FETCH_retval(type) \ |
96 | __kprobes void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs, \ | 96 | void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs, \ |
97 | void *dummy, void *dest) \ | 97 | void *dummy, void *dest) \ |
98 | { \ | 98 | { \ |
99 | *(type *)dest = (type)regs_return_value(regs); \ | 99 | *(type *)dest = (type)regs_return_value(regs); \ |
100 | } | 100 | } \ |
101 | NOKPROBE_SYMBOL(FETCH_FUNC_NAME(retval, type)); | ||
101 | DEFINE_BASIC_FETCH_FUNCS(retval) | 102 | DEFINE_BASIC_FETCH_FUNCS(retval) |
102 | /* No string on the retval */ | 103 | /* No string on the retval */ |
103 | #define fetch_retval_string NULL | 104 | #define fetch_retval_string NULL |
@@ -112,8 +113,8 @@ struct deref_fetch_param { | |||
112 | }; | 113 | }; |
113 | 114 | ||
114 | #define DEFINE_FETCH_deref(type) \ | 115 | #define DEFINE_FETCH_deref(type) \ |
115 | __kprobes void FETCH_FUNC_NAME(deref, type)(struct pt_regs *regs, \ | 116 | void FETCH_FUNC_NAME(deref, type)(struct pt_regs *regs, \ |
116 | void *data, void *dest) \ | 117 | void *data, void *dest) \ |
117 | { \ | 118 | { \ |
118 | struct deref_fetch_param *dprm = data; \ | 119 | struct deref_fetch_param *dprm = data; \ |
119 | unsigned long addr; \ | 120 | unsigned long addr; \ |
@@ -123,12 +124,13 @@ __kprobes void FETCH_FUNC_NAME(deref, type)(struct pt_regs *regs, \ | |||
123 | dprm->fetch(regs, (void *)addr, dest); \ | 124 | dprm->fetch(regs, (void *)addr, dest); \ |
124 | } else \ | 125 | } else \ |
125 | *(type *)dest = 0; \ | 126 | *(type *)dest = 0; \ |
126 | } | 127 | } \ |
128 | NOKPROBE_SYMBOL(FETCH_FUNC_NAME(deref, type)); | ||
127 | DEFINE_BASIC_FETCH_FUNCS(deref) | 129 | DEFINE_BASIC_FETCH_FUNCS(deref) |
128 | DEFINE_FETCH_deref(string) | 130 | DEFINE_FETCH_deref(string) |
129 | 131 | ||
130 | __kprobes void FETCH_FUNC_NAME(deref, string_size)(struct pt_regs *regs, | 132 | void FETCH_FUNC_NAME(deref, string_size)(struct pt_regs *regs, |
131 | void *data, void *dest) | 133 | void *data, void *dest) |
132 | { | 134 | { |
133 | struct deref_fetch_param *dprm = data; | 135 | struct deref_fetch_param *dprm = data; |
134 | unsigned long addr; | 136 | unsigned long addr; |
@@ -140,16 +142,18 @@ __kprobes void FETCH_FUNC_NAME(deref, string_size)(struct pt_regs *regs, | |||
140 | } else | 142 | } else |
141 | *(string_size *)dest = 0; | 143 | *(string_size *)dest = 0; |
142 | } | 144 | } |
145 | NOKPROBE_SYMBOL(FETCH_FUNC_NAME(deref, string_size)); | ||
143 | 146 | ||
144 | static __kprobes void update_deref_fetch_param(struct deref_fetch_param *data) | 147 | static void update_deref_fetch_param(struct deref_fetch_param *data) |
145 | { | 148 | { |
146 | if (CHECK_FETCH_FUNCS(deref, data->orig.fn)) | 149 | if (CHECK_FETCH_FUNCS(deref, data->orig.fn)) |
147 | update_deref_fetch_param(data->orig.data); | 150 | update_deref_fetch_param(data->orig.data); |
148 | else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn)) | 151 | else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn)) |
149 | update_symbol_cache(data->orig.data); | 152 | update_symbol_cache(data->orig.data); |
150 | } | 153 | } |
154 | NOKPROBE_SYMBOL(update_deref_fetch_param); | ||
151 | 155 | ||
152 | static __kprobes void free_deref_fetch_param(struct deref_fetch_param *data) | 156 | static void free_deref_fetch_param(struct deref_fetch_param *data) |
153 | { | 157 | { |
154 | if (CHECK_FETCH_FUNCS(deref, data->orig.fn)) | 158 | if (CHECK_FETCH_FUNCS(deref, data->orig.fn)) |
155 | free_deref_fetch_param(data->orig.data); | 159 | free_deref_fetch_param(data->orig.data); |
@@ -157,6 +161,7 @@ static __kprobes void free_deref_fetch_param(struct deref_fetch_param *data) | |||
157 | free_symbol_cache(data->orig.data); | 161 | free_symbol_cache(data->orig.data); |
158 | kfree(data); | 162 | kfree(data); |
159 | } | 163 | } |
164 | NOKPROBE_SYMBOL(free_deref_fetch_param); | ||
160 | 165 | ||
161 | /* Bitfield fetch function */ | 166 | /* Bitfield fetch function */ |
162 | struct bitfield_fetch_param { | 167 | struct bitfield_fetch_param { |
@@ -166,8 +171,8 @@ struct bitfield_fetch_param { | |||
166 | }; | 171 | }; |
167 | 172 | ||
168 | #define DEFINE_FETCH_bitfield(type) \ | 173 | #define DEFINE_FETCH_bitfield(type) \ |
169 | __kprobes void FETCH_FUNC_NAME(bitfield, type)(struct pt_regs *regs, \ | 174 | void FETCH_FUNC_NAME(bitfield, type)(struct pt_regs *regs, \ |
170 | void *data, void *dest) \ | 175 | void *data, void *dest) \ |
171 | { \ | 176 | { \ |
172 | struct bitfield_fetch_param *bprm = data; \ | 177 | struct bitfield_fetch_param *bprm = data; \ |
173 | type buf = 0; \ | 178 | type buf = 0; \ |
@@ -177,8 +182,8 @@ __kprobes void FETCH_FUNC_NAME(bitfield, type)(struct pt_regs *regs, \ | |||
177 | buf >>= bprm->low_shift; \ | 182 | buf >>= bprm->low_shift; \ |
178 | } \ | 183 | } \ |
179 | *(type *)dest = buf; \ | 184 | *(type *)dest = buf; \ |
180 | } | 185 | } \ |
181 | 186 | NOKPROBE_SYMBOL(FETCH_FUNC_NAME(bitfield, type)); | |
182 | DEFINE_BASIC_FETCH_FUNCS(bitfield) | 187 | DEFINE_BASIC_FETCH_FUNCS(bitfield) |
183 | #define fetch_bitfield_string NULL | 188 | #define fetch_bitfield_string NULL |
184 | #define fetch_bitfield_string_size NULL | 189 | #define fetch_bitfield_string_size NULL |
@@ -255,17 +260,17 @@ fail: | |||
255 | } | 260 | } |
256 | 261 | ||
257 | /* Special function : only accept unsigned long */ | 262 | /* Special function : only accept unsigned long */ |
258 | static __kprobes void fetch_kernel_stack_address(struct pt_regs *regs, | 263 | static void fetch_kernel_stack_address(struct pt_regs *regs, void *dummy, void *dest) |
259 | void *dummy, void *dest) | ||
260 | { | 264 | { |
261 | *(unsigned long *)dest = kernel_stack_pointer(regs); | 265 | *(unsigned long *)dest = kernel_stack_pointer(regs); |
262 | } | 266 | } |
267 | NOKPROBE_SYMBOL(fetch_kernel_stack_address); | ||
263 | 268 | ||
264 | static __kprobes void fetch_user_stack_address(struct pt_regs *regs, | 269 | static void fetch_user_stack_address(struct pt_regs *regs, void *dummy, void *dest) |
265 | void *dummy, void *dest) | ||
266 | { | 270 | { |
267 | *(unsigned long *)dest = user_stack_pointer(regs); | 271 | *(unsigned long *)dest = user_stack_pointer(regs); |
268 | } | 272 | } |
273 | NOKPROBE_SYMBOL(fetch_user_stack_address); | ||
269 | 274 | ||
270 | static fetch_func_t get_fetch_size_function(const struct fetch_type *type, | 275 | static fetch_func_t get_fetch_size_function(const struct fetch_type *type, |
271 | fetch_func_t orig_fn, | 276 | fetch_func_t orig_fn, |
diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index fb1ab5dfbd42..4f815fbce16d 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h | |||
@@ -81,13 +81,13 @@ | |||
81 | */ | 81 | */ |
82 | #define convert_rloc_to_loc(dl, offs) ((u32)(dl) + (offs)) | 82 | #define convert_rloc_to_loc(dl, offs) ((u32)(dl) + (offs)) |
83 | 83 | ||
84 | static inline void *get_rloc_data(u32 *dl) | 84 | static nokprobe_inline void *get_rloc_data(u32 *dl) |
85 | { | 85 | { |
86 | return (u8 *)dl + get_rloc_offs(*dl); | 86 | return (u8 *)dl + get_rloc_offs(*dl); |
87 | } | 87 | } |
88 | 88 | ||
89 | /* For data_loc conversion */ | 89 | /* For data_loc conversion */ |
90 | static inline void *get_loc_data(u32 *dl, void *ent) | 90 | static nokprobe_inline void *get_loc_data(u32 *dl, void *ent) |
91 | { | 91 | { |
92 | return (u8 *)ent + get_rloc_offs(*dl); | 92 | return (u8 *)ent + get_rloc_offs(*dl); |
93 | } | 93 | } |
@@ -136,9 +136,8 @@ typedef u32 string_size; | |||
136 | 136 | ||
137 | /* Printing in basic type function template */ | 137 | /* Printing in basic type function template */ |
138 | #define DECLARE_BASIC_PRINT_TYPE_FUNC(type) \ | 138 | #define DECLARE_BASIC_PRINT_TYPE_FUNC(type) \ |
139 | __kprobes int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s, \ | 139 | int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s, const char *name, \ |
140 | const char *name, \ | 140 | void *data, void *ent); \ |
141 | void *data, void *ent); \ | ||
142 | extern const char PRINT_TYPE_FMT_NAME(type)[] | 141 | extern const char PRINT_TYPE_FMT_NAME(type)[] |
143 | 142 | ||
144 | DECLARE_BASIC_PRINT_TYPE_FUNC(u8); | 143 | DECLARE_BASIC_PRINT_TYPE_FUNC(u8); |
@@ -303,7 +302,7 @@ static inline bool trace_probe_is_registered(struct trace_probe *tp) | |||
303 | return !!(tp->flags & TP_FLAG_REGISTERED); | 302 | return !!(tp->flags & TP_FLAG_REGISTERED); |
304 | } | 303 | } |
305 | 304 | ||
306 | static inline __kprobes void call_fetch(struct fetch_param *fprm, | 305 | static nokprobe_inline void call_fetch(struct fetch_param *fprm, |
307 | struct pt_regs *regs, void *dest) | 306 | struct pt_regs *regs, void *dest) |
308 | { | 307 | { |
309 | return fprm->fn(regs, fprm->data, dest); | 308 | return fprm->fn(regs, fprm->data, dest); |
@@ -351,7 +350,7 @@ extern ssize_t traceprobe_probes_write(struct file *file, | |||
351 | extern int traceprobe_command(const char *buf, int (*createfn)(int, char**)); | 350 | extern int traceprobe_command(const char *buf, int (*createfn)(int, char**)); |
352 | 351 | ||
353 | /* Sum up total data length for dynamic arraies (strings) */ | 352 | /* Sum up total data length for dynamic arraies (strings) */ |
354 | static inline __kprobes int | 353 | static nokprobe_inline int |
355 | __get_data_size(struct trace_probe *tp, struct pt_regs *regs) | 354 | __get_data_size(struct trace_probe *tp, struct pt_regs *regs) |
356 | { | 355 | { |
357 | int i, ret = 0; | 356 | int i, ret = 0; |
@@ -367,7 +366,7 @@ __get_data_size(struct trace_probe *tp, struct pt_regs *regs) | |||
367 | } | 366 | } |
368 | 367 | ||
369 | /* Store the value of each argument */ | 368 | /* Store the value of each argument */ |
370 | static inline __kprobes void | 369 | static nokprobe_inline void |
371 | store_trace_args(int ent_size, struct trace_probe *tp, struct pt_regs *regs, | 370 | store_trace_args(int ent_size, struct trace_probe *tp, struct pt_regs *regs, |
372 | u8 *data, int maxlen) | 371 | u8 *data, int maxlen) |
373 | { | 372 | { |