diff options
Diffstat (limited to 'kernel/trace/trace_kprobe.c')
| -rw-r--r-- | kernel/trace/trace_kprobe.c | 66 |
1 files changed, 39 insertions, 27 deletions
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 |
