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 | { |
