diff options
Diffstat (limited to 'kernel/trace/trace_kprobe.c')
| -rw-r--r-- | kernel/trace/trace_kprobe.c | 306 |
1 files changed, 120 insertions, 186 deletions
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 6ea90c0e2c96..505c92273b1a 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
| @@ -91,11 +91,6 @@ static __kprobes unsigned long fetch_memory(struct pt_regs *regs, void *addr) | |||
| 91 | return retval; | 91 | return retval; |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | static __kprobes unsigned long fetch_argument(struct pt_regs *regs, void *num) | ||
| 95 | { | ||
| 96 | return regs_get_argument_nth(regs, (unsigned int)((unsigned long)num)); | ||
| 97 | } | ||
| 98 | |||
| 99 | static __kprobes unsigned long fetch_retvalue(struct pt_regs *regs, | 94 | static __kprobes unsigned long fetch_retvalue(struct pt_regs *regs, |
| 100 | void *dummy) | 95 | void *dummy) |
| 101 | { | 96 | { |
| @@ -231,9 +226,7 @@ static int probe_arg_string(char *buf, size_t n, struct fetch_func *ff) | |||
| 231 | { | 226 | { |
| 232 | int ret = -EINVAL; | 227 | int ret = -EINVAL; |
| 233 | 228 | ||
| 234 | if (ff->func == fetch_argument) | 229 | if (ff->func == fetch_register) { |
| 235 | ret = snprintf(buf, n, "$arg%lu", (unsigned long)ff->data); | ||
| 236 | else if (ff->func == fetch_register) { | ||
| 237 | const char *name; | 230 | const char *name; |
| 238 | name = regs_query_register_name((unsigned int)((long)ff->data)); | 231 | name = regs_query_register_name((unsigned int)((long)ff->data)); |
| 239 | ret = snprintf(buf, n, "%%%s", name); | 232 | ret = snprintf(buf, n, "%%%s", name); |
| @@ -489,14 +482,6 @@ static int parse_probe_vars(char *arg, struct fetch_func *ff, int is_return) | |||
| 489 | } | 482 | } |
| 490 | } else | 483 | } else |
| 491 | ret = -EINVAL; | 484 | ret = -EINVAL; |
| 492 | } else if (strncmp(arg, "arg", 3) == 0 && isdigit(arg[3])) { | ||
| 493 | ret = strict_strtoul(arg + 3, 10, ¶m); | ||
| 494 | if (ret || param > PARAM_MAX_ARGS) | ||
| 495 | ret = -EINVAL; | ||
| 496 | else { | ||
| 497 | ff->func = fetch_argument; | ||
| 498 | ff->data = (void *)param; | ||
| 499 | } | ||
| 500 | } else | 485 | } else |
| 501 | ret = -EINVAL; | 486 | ret = -EINVAL; |
| 502 | return ret; | 487 | return ret; |
| @@ -611,7 +596,6 @@ static int create_trace_probe(int argc, char **argv) | |||
| 611 | * - Add kprobe: p[:[GRP/]EVENT] KSYM[+OFFS]|KADDR [FETCHARGS] | 596 | * - Add kprobe: p[:[GRP/]EVENT] KSYM[+OFFS]|KADDR [FETCHARGS] |
| 612 | * - Add kretprobe: r[:[GRP/]EVENT] KSYM[+0] [FETCHARGS] | 597 | * - Add kretprobe: r[:[GRP/]EVENT] KSYM[+0] [FETCHARGS] |
| 613 | * Fetch args: | 598 | * Fetch args: |
| 614 | * $argN : fetch Nth of function argument. (N:0-) | ||
| 615 | * $retval : fetch return value | 599 | * $retval : fetch return value |
| 616 | * $stack : fetch stack address | 600 | * $stack : fetch stack address |
| 617 | * $stackN : fetch Nth of stack (N:0-) | 601 | * $stackN : fetch Nth of stack (N:0-) |
| @@ -651,12 +635,12 @@ static int create_trace_probe(int argc, char **argv) | |||
| 651 | event = strchr(group, '/') + 1; | 635 | event = strchr(group, '/') + 1; |
| 652 | event[-1] = '\0'; | 636 | event[-1] = '\0'; |
| 653 | if (strlen(group) == 0) { | 637 | if (strlen(group) == 0) { |
| 654 | pr_info("Group name is not specifiled\n"); | 638 | pr_info("Group name is not specified\n"); |
| 655 | return -EINVAL; | 639 | return -EINVAL; |
| 656 | } | 640 | } |
| 657 | } | 641 | } |
| 658 | if (strlen(event) == 0) { | 642 | if (strlen(event) == 0) { |
| 659 | pr_info("Event name is not specifiled\n"); | 643 | pr_info("Event name is not specified\n"); |
| 660 | return -EINVAL; | 644 | return -EINVAL; |
| 661 | } | 645 | } |
| 662 | } | 646 | } |
| @@ -689,7 +673,7 @@ static int create_trace_probe(int argc, char **argv) | |||
| 689 | return -EINVAL; | 673 | return -EINVAL; |
| 690 | } | 674 | } |
| 691 | /* an address specified */ | 675 | /* an address specified */ |
| 692 | ret = strict_strtoul(&argv[0][2], 0, (unsigned long *)&addr); | 676 | ret = strict_strtoul(&argv[1][0], 0, (unsigned long *)&addr); |
| 693 | if (ret) { | 677 | if (ret) { |
| 694 | pr_info("Failed to parse address.\n"); | 678 | pr_info("Failed to parse address.\n"); |
| 695 | return ret; | 679 | return ret; |
| @@ -958,7 +942,7 @@ static const struct file_operations kprobe_profile_ops = { | |||
| 958 | }; | 942 | }; |
| 959 | 943 | ||
| 960 | /* Kprobe handler */ | 944 | /* Kprobe handler */ |
| 961 | static __kprobes int kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) | 945 | static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) |
| 962 | { | 946 | { |
| 963 | struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp); | 947 | struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp); |
| 964 | struct kprobe_trace_entry *entry; | 948 | struct kprobe_trace_entry *entry; |
| @@ -978,7 +962,7 @@ static __kprobes int kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) | |||
| 978 | event = trace_current_buffer_lock_reserve(&buffer, call->id, size, | 962 | event = trace_current_buffer_lock_reserve(&buffer, call->id, size, |
| 979 | irq_flags, pc); | 963 | irq_flags, pc); |
| 980 | if (!event) | 964 | if (!event) |
| 981 | return 0; | 965 | return; |
| 982 | 966 | ||
| 983 | entry = ring_buffer_event_data(event); | 967 | entry = ring_buffer_event_data(event); |
| 984 | entry->nargs = tp->nr_args; | 968 | entry->nargs = tp->nr_args; |
| @@ -988,11 +972,10 @@ static __kprobes int kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) | |||
| 988 | 972 | ||
| 989 | if (!filter_current_check_discard(buffer, call, entry, event)) | 973 | if (!filter_current_check_discard(buffer, call, entry, event)) |
| 990 | trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc); | 974 | trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc); |
| 991 | return 0; | ||
| 992 | } | 975 | } |
| 993 | 976 | ||
| 994 | /* Kretprobe handler */ | 977 | /* Kretprobe handler */ |
| 995 | static __kprobes int kretprobe_trace_func(struct kretprobe_instance *ri, | 978 | static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri, |
| 996 | struct pt_regs *regs) | 979 | struct pt_regs *regs) |
| 997 | { | 980 | { |
| 998 | struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp); | 981 | struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp); |
| @@ -1011,7 +994,7 @@ static __kprobes int kretprobe_trace_func(struct kretprobe_instance *ri, | |||
| 1011 | event = trace_current_buffer_lock_reserve(&buffer, call->id, size, | 994 | event = trace_current_buffer_lock_reserve(&buffer, call->id, size, |
| 1012 | irq_flags, pc); | 995 | irq_flags, pc); |
| 1013 | if (!event) | 996 | if (!event) |
| 1014 | return 0; | 997 | return; |
| 1015 | 998 | ||
| 1016 | entry = ring_buffer_event_data(event); | 999 | entry = ring_buffer_event_data(event); |
| 1017 | entry->nargs = tp->nr_args; | 1000 | entry->nargs = tp->nr_args; |
| @@ -1022,8 +1005,6 @@ static __kprobes int kretprobe_trace_func(struct kretprobe_instance *ri, | |||
| 1022 | 1005 | ||
| 1023 | if (!filter_current_check_discard(buffer, call, entry, event)) | 1006 | if (!filter_current_check_discard(buffer, call, entry, event)) |
| 1024 | trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc); | 1007 | trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc); |
| 1025 | |||
| 1026 | return 0; | ||
| 1027 | } | 1008 | } |
| 1028 | 1009 | ||
| 1029 | /* Event entry printers */ | 1010 | /* Event entry printers */ |
| @@ -1174,213 +1155,123 @@ static int kretprobe_event_define_fields(struct ftrace_event_call *event_call) | |||
| 1174 | return 0; | 1155 | return 0; |
| 1175 | } | 1156 | } |
| 1176 | 1157 | ||
| 1177 | static int __probe_event_show_format(struct trace_seq *s, | 1158 | static int __set_print_fmt(struct trace_probe *tp, char *buf, int len) |
| 1178 | struct trace_probe *tp, const char *fmt, | ||
| 1179 | const char *arg) | ||
| 1180 | { | 1159 | { |
| 1181 | int i; | 1160 | int i; |
| 1161 | int pos = 0; | ||
| 1182 | 1162 | ||
| 1183 | /* Show format */ | 1163 | const char *fmt, *arg; |
| 1184 | if (!trace_seq_printf(s, "\nprint fmt: \"%s", fmt)) | ||
| 1185 | return 0; | ||
| 1186 | 1164 | ||
| 1187 | for (i = 0; i < tp->nr_args; i++) | 1165 | if (!probe_is_return(tp)) { |
| 1188 | if (!trace_seq_printf(s, " %s=%%lx", tp->args[i].name)) | 1166 | fmt = "(%lx)"; |
| 1189 | return 0; | 1167 | arg = "REC->" FIELD_STRING_IP; |
| 1168 | } else { | ||
| 1169 | fmt = "(%lx <- %lx)"; | ||
| 1170 | arg = "REC->" FIELD_STRING_FUNC ", REC->" FIELD_STRING_RETIP; | ||
| 1171 | } | ||
| 1190 | 1172 | ||
| 1191 | if (!trace_seq_printf(s, "\", %s", arg)) | 1173 | /* When len=0, we just calculate the needed length */ |
| 1192 | return 0; | 1174 | #define LEN_OR_ZERO (len ? len - pos : 0) |
| 1193 | 1175 | ||
| 1194 | for (i = 0; i < tp->nr_args; i++) | 1176 | pos += snprintf(buf + pos, LEN_OR_ZERO, "\"%s", fmt); |
| 1195 | if (!trace_seq_printf(s, ", REC->%s", tp->args[i].name)) | ||
| 1196 | return 0; | ||
| 1197 | |||
| 1198 | return trace_seq_puts(s, "\n"); | ||
| 1199 | } | ||
| 1200 | 1177 | ||
| 1201 | #undef SHOW_FIELD | 1178 | for (i = 0; i < tp->nr_args; i++) { |
| 1202 | #define SHOW_FIELD(type, item, name) \ | 1179 | pos += snprintf(buf + pos, LEN_OR_ZERO, " %s=%%lx", |
| 1203 | do { \ | 1180 | tp->args[i].name); |
| 1204 | ret = trace_seq_printf(s, "\tfield:" #type " %s;\t" \ | 1181 | } |
| 1205 | "offset:%u;\tsize:%u;\tsigned:%d;\n", name,\ | ||
| 1206 | (unsigned int)offsetof(typeof(field), item),\ | ||
| 1207 | (unsigned int)sizeof(type), \ | ||
| 1208 | is_signed_type(type)); \ | ||
| 1209 | if (!ret) \ | ||
| 1210 | return 0; \ | ||
| 1211 | } while (0) | ||
| 1212 | 1182 | ||
| 1213 | static int kprobe_event_show_format(struct ftrace_event_call *call, | 1183 | pos += snprintf(buf + pos, LEN_OR_ZERO, "\", %s", arg); |
| 1214 | struct trace_seq *s) | ||
| 1215 | { | ||
| 1216 | struct kprobe_trace_entry field __attribute__((unused)); | ||
| 1217 | int ret, i; | ||
| 1218 | struct trace_probe *tp = (struct trace_probe *)call->data; | ||
| 1219 | 1184 | ||
| 1220 | SHOW_FIELD(unsigned long, ip, FIELD_STRING_IP); | 1185 | for (i = 0; i < tp->nr_args; i++) { |
| 1221 | SHOW_FIELD(int, nargs, FIELD_STRING_NARGS); | 1186 | pos += snprintf(buf + pos, LEN_OR_ZERO, ", REC->%s", |
| 1187 | tp->args[i].name); | ||
| 1188 | } | ||
| 1222 | 1189 | ||
| 1223 | /* Show fields */ | 1190 | #undef LEN_OR_ZERO |
| 1224 | for (i = 0; i < tp->nr_args; i++) | ||
| 1225 | SHOW_FIELD(unsigned long, args[i], tp->args[i].name); | ||
| 1226 | trace_seq_puts(s, "\n"); | ||
| 1227 | 1191 | ||
| 1228 | return __probe_event_show_format(s, tp, "(%lx)", | 1192 | /* return the length of print_fmt */ |
| 1229 | "REC->" FIELD_STRING_IP); | 1193 | return pos; |
| 1230 | } | 1194 | } |
| 1231 | 1195 | ||
| 1232 | static int kretprobe_event_show_format(struct ftrace_event_call *call, | 1196 | static int set_print_fmt(struct trace_probe *tp) |
| 1233 | struct trace_seq *s) | ||
| 1234 | { | 1197 | { |
| 1235 | struct kretprobe_trace_entry field __attribute__((unused)); | 1198 | int len; |
| 1236 | int ret, i; | 1199 | char *print_fmt; |
| 1237 | struct trace_probe *tp = (struct trace_probe *)call->data; | ||
| 1238 | 1200 | ||
| 1239 | SHOW_FIELD(unsigned long, func, FIELD_STRING_FUNC); | 1201 | /* First: called with 0 length to calculate the needed length */ |
| 1240 | SHOW_FIELD(unsigned long, ret_ip, FIELD_STRING_RETIP); | 1202 | len = __set_print_fmt(tp, NULL, 0); |
| 1241 | SHOW_FIELD(int, nargs, FIELD_STRING_NARGS); | 1203 | print_fmt = kmalloc(len + 1, GFP_KERNEL); |
| 1204 | if (!print_fmt) | ||
| 1205 | return -ENOMEM; | ||
| 1242 | 1206 | ||
| 1243 | /* Show fields */ | 1207 | /* Second: actually write the @print_fmt */ |
| 1244 | for (i = 0; i < tp->nr_args; i++) | 1208 | __set_print_fmt(tp, print_fmt, len + 1); |
| 1245 | SHOW_FIELD(unsigned long, args[i], tp->args[i].name); | 1209 | tp->call.print_fmt = print_fmt; |
| 1246 | trace_seq_puts(s, "\n"); | ||
| 1247 | 1210 | ||
| 1248 | return __probe_event_show_format(s, tp, "(%lx <- %lx)", | 1211 | return 0; |
| 1249 | "REC->" FIELD_STRING_FUNC | ||
| 1250 | ", REC->" FIELD_STRING_RETIP); | ||
| 1251 | } | 1212 | } |
| 1252 | 1213 | ||
| 1253 | #ifdef CONFIG_EVENT_PROFILE | 1214 | #ifdef CONFIG_PERF_EVENTS |
| 1254 | 1215 | ||
| 1255 | /* Kprobe profile handler */ | 1216 | /* Kprobe profile handler */ |
| 1256 | static __kprobes int kprobe_profile_func(struct kprobe *kp, | 1217 | static __kprobes void kprobe_profile_func(struct kprobe *kp, |
| 1257 | struct pt_regs *regs) | 1218 | struct pt_regs *regs) |
| 1258 | { | 1219 | { |
| 1259 | struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp); | 1220 | struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp); |
| 1260 | struct ftrace_event_call *call = &tp->call; | 1221 | struct ftrace_event_call *call = &tp->call; |
| 1261 | struct kprobe_trace_entry *entry; | 1222 | struct kprobe_trace_entry *entry; |
| 1262 | struct trace_entry *ent; | 1223 | int size, __size, i; |
| 1263 | int size, __size, i, pc, __cpu; | ||
| 1264 | unsigned long irq_flags; | 1224 | unsigned long irq_flags; |
| 1265 | char *trace_buf; | ||
| 1266 | char *raw_data; | ||
| 1267 | int rctx; | 1225 | int rctx; |
| 1268 | 1226 | ||
| 1269 | pc = preempt_count(); | ||
| 1270 | __size = SIZEOF_KPROBE_TRACE_ENTRY(tp->nr_args); | 1227 | __size = SIZEOF_KPROBE_TRACE_ENTRY(tp->nr_args); |
| 1271 | size = ALIGN(__size + sizeof(u32), sizeof(u64)); | 1228 | size = ALIGN(__size + sizeof(u32), sizeof(u64)); |
| 1272 | size -= sizeof(u32); | 1229 | size -= sizeof(u32); |
| 1273 | if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE, | 1230 | if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE, |
| 1274 | "profile buffer not large enough")) | 1231 | "profile buffer not large enough")) |
| 1275 | return 0; | 1232 | return; |
| 1276 | |||
| 1277 | /* | ||
| 1278 | * Protect the non nmi buffer | ||
| 1279 | * This also protects the rcu read side | ||
| 1280 | */ | ||
| 1281 | local_irq_save(irq_flags); | ||
| 1282 | |||
| 1283 | rctx = perf_swevent_get_recursion_context(); | ||
| 1284 | if (rctx < 0) | ||
| 1285 | goto end_recursion; | ||
| 1286 | |||
| 1287 | __cpu = smp_processor_id(); | ||
| 1288 | |||
| 1289 | if (in_nmi()) | ||
| 1290 | trace_buf = rcu_dereference(perf_trace_buf_nmi); | ||
| 1291 | else | ||
| 1292 | trace_buf = rcu_dereference(perf_trace_buf); | ||
| 1293 | 1233 | ||
| 1294 | if (!trace_buf) | 1234 | entry = ftrace_perf_buf_prepare(size, call->id, &rctx, &irq_flags); |
| 1295 | goto end; | 1235 | if (!entry) |
| 1296 | 1236 | return; | |
| 1297 | raw_data = per_cpu_ptr(trace_buf, __cpu); | ||
| 1298 | |||
| 1299 | /* Zero dead bytes from alignment to avoid buffer leak to userspace */ | ||
| 1300 | *(u64 *)(&raw_data[size - sizeof(u64)]) = 0ULL; | ||
| 1301 | entry = (struct kprobe_trace_entry *)raw_data; | ||
| 1302 | ent = &entry->ent; | ||
| 1303 | 1237 | ||
| 1304 | tracing_generic_entry_update(ent, irq_flags, pc); | ||
| 1305 | ent->type = call->id; | ||
| 1306 | entry->nargs = tp->nr_args; | 1238 | entry->nargs = tp->nr_args; |
| 1307 | entry->ip = (unsigned long)kp->addr; | 1239 | entry->ip = (unsigned long)kp->addr; |
| 1308 | for (i = 0; i < tp->nr_args; i++) | 1240 | for (i = 0; i < tp->nr_args; i++) |
| 1309 | entry->args[i] = call_fetch(&tp->args[i].fetch, regs); | 1241 | entry->args[i] = call_fetch(&tp->args[i].fetch, regs); |
| 1310 | perf_tp_event(call->id, entry->ip, 1, entry, size); | ||
| 1311 | |||
| 1312 | end: | ||
| 1313 | perf_swevent_put_recursion_context(rctx); | ||
| 1314 | end_recursion: | ||
| 1315 | local_irq_restore(irq_flags); | ||
| 1316 | 1242 | ||
| 1317 | return 0; | 1243 | ftrace_perf_buf_submit(entry, size, rctx, entry->ip, 1, irq_flags); |
| 1318 | } | 1244 | } |
| 1319 | 1245 | ||
| 1320 | /* Kretprobe profile handler */ | 1246 | /* Kretprobe profile handler */ |
| 1321 | static __kprobes int kretprobe_profile_func(struct kretprobe_instance *ri, | 1247 | static __kprobes void kretprobe_profile_func(struct kretprobe_instance *ri, |
| 1322 | struct pt_regs *regs) | 1248 | struct pt_regs *regs) |
| 1323 | { | 1249 | { |
| 1324 | struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp); | 1250 | struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp); |
| 1325 | struct ftrace_event_call *call = &tp->call; | 1251 | struct ftrace_event_call *call = &tp->call; |
| 1326 | struct kretprobe_trace_entry *entry; | 1252 | struct kretprobe_trace_entry *entry; |
| 1327 | struct trace_entry *ent; | 1253 | int size, __size, i; |
| 1328 | int size, __size, i, pc, __cpu; | ||
| 1329 | unsigned long irq_flags; | 1254 | unsigned long irq_flags; |
| 1330 | char *trace_buf; | ||
| 1331 | char *raw_data; | ||
| 1332 | int rctx; | 1255 | int rctx; |
| 1333 | 1256 | ||
| 1334 | pc = preempt_count(); | ||
| 1335 | __size = SIZEOF_KRETPROBE_TRACE_ENTRY(tp->nr_args); | 1257 | __size = SIZEOF_KRETPROBE_TRACE_ENTRY(tp->nr_args); |
| 1336 | size = ALIGN(__size + sizeof(u32), sizeof(u64)); | 1258 | size = ALIGN(__size + sizeof(u32), sizeof(u64)); |
| 1337 | size -= sizeof(u32); | 1259 | size -= sizeof(u32); |
| 1338 | if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE, | 1260 | if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE, |
| 1339 | "profile buffer not large enough")) | 1261 | "profile buffer not large enough")) |
| 1340 | return 0; | 1262 | return; |
| 1341 | |||
| 1342 | /* | ||
| 1343 | * Protect the non nmi buffer | ||
| 1344 | * This also protects the rcu read side | ||
| 1345 | */ | ||
| 1346 | local_irq_save(irq_flags); | ||
| 1347 | |||
| 1348 | rctx = perf_swevent_get_recursion_context(); | ||
| 1349 | if (rctx < 0) | ||
| 1350 | goto end_recursion; | ||
| 1351 | |||
| 1352 | __cpu = smp_processor_id(); | ||
| 1353 | 1263 | ||
| 1354 | if (in_nmi()) | 1264 | entry = ftrace_perf_buf_prepare(size, call->id, &rctx, &irq_flags); |
| 1355 | trace_buf = rcu_dereference(perf_trace_buf_nmi); | 1265 | if (!entry) |
| 1356 | else | 1266 | return; |
| 1357 | trace_buf = rcu_dereference(perf_trace_buf); | ||
| 1358 | |||
| 1359 | if (!trace_buf) | ||
| 1360 | goto end; | ||
| 1361 | |||
| 1362 | raw_data = per_cpu_ptr(trace_buf, __cpu); | ||
| 1363 | |||
| 1364 | /* Zero dead bytes from alignment to avoid buffer leak to userspace */ | ||
| 1365 | *(u64 *)(&raw_data[size - sizeof(u64)]) = 0ULL; | ||
| 1366 | entry = (struct kretprobe_trace_entry *)raw_data; | ||
| 1367 | ent = &entry->ent; | ||
| 1368 | 1267 | ||
| 1369 | tracing_generic_entry_update(ent, irq_flags, pc); | ||
| 1370 | ent->type = call->id; | ||
| 1371 | entry->nargs = tp->nr_args; | 1268 | entry->nargs = tp->nr_args; |
| 1372 | entry->func = (unsigned long)tp->rp.kp.addr; | 1269 | entry->func = (unsigned long)tp->rp.kp.addr; |
| 1373 | entry->ret_ip = (unsigned long)ri->ret_addr; | 1270 | entry->ret_ip = (unsigned long)ri->ret_addr; |
| 1374 | for (i = 0; i < tp->nr_args; i++) | 1271 | for (i = 0; i < tp->nr_args; i++) |
| 1375 | entry->args[i] = call_fetch(&tp->args[i].fetch, regs); | 1272 | entry->args[i] = call_fetch(&tp->args[i].fetch, regs); |
| 1376 | perf_tp_event(call->id, entry->ret_ip, 1, entry, size); | ||
| 1377 | |||
| 1378 | end: | ||
| 1379 | perf_swevent_put_recursion_context(rctx); | ||
| 1380 | end_recursion: | ||
| 1381 | local_irq_restore(irq_flags); | ||
| 1382 | 1273 | ||
| 1383 | return 0; | 1274 | ftrace_perf_buf_submit(entry, size, rctx, entry->ret_ip, 1, irq_flags); |
| 1384 | } | 1275 | } |
| 1385 | 1276 | ||
| 1386 | static int probe_profile_enable(struct ftrace_event_call *call) | 1277 | static int probe_profile_enable(struct ftrace_event_call *call) |
| @@ -1408,7 +1299,7 @@ static void probe_profile_disable(struct ftrace_event_call *call) | |||
| 1408 | disable_kprobe(&tp->rp.kp); | 1299 | disable_kprobe(&tp->rp.kp); |
| 1409 | } | 1300 | } |
| 1410 | } | 1301 | } |
| 1411 | #endif /* CONFIG_EVENT_PROFILE */ | 1302 | #endif /* CONFIG_PERF_EVENTS */ |
| 1412 | 1303 | ||
| 1413 | 1304 | ||
| 1414 | static __kprobes | 1305 | static __kprobes |
| @@ -1418,10 +1309,10 @@ int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs) | |||
| 1418 | 1309 | ||
| 1419 | if (tp->flags & TP_FLAG_TRACE) | 1310 | if (tp->flags & TP_FLAG_TRACE) |
| 1420 | kprobe_trace_func(kp, regs); | 1311 | kprobe_trace_func(kp, regs); |
| 1421 | #ifdef CONFIG_EVENT_PROFILE | 1312 | #ifdef CONFIG_PERF_EVENTS |
| 1422 | if (tp->flags & TP_FLAG_PROFILE) | 1313 | if (tp->flags & TP_FLAG_PROFILE) |
| 1423 | kprobe_profile_func(kp, regs); | 1314 | kprobe_profile_func(kp, regs); |
| 1424 | #endif /* CONFIG_EVENT_PROFILE */ | 1315 | #endif |
| 1425 | return 0; /* We don't tweek kernel, so just return 0 */ | 1316 | return 0; /* We don't tweek kernel, so just return 0 */ |
| 1426 | } | 1317 | } |
| 1427 | 1318 | ||
| @@ -1432,10 +1323,10 @@ int kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs) | |||
| 1432 | 1323 | ||
| 1433 | if (tp->flags & TP_FLAG_TRACE) | 1324 | if (tp->flags & TP_FLAG_TRACE) |
| 1434 | kretprobe_trace_func(ri, regs); | 1325 | kretprobe_trace_func(ri, regs); |
| 1435 | #ifdef CONFIG_EVENT_PROFILE | 1326 | #ifdef CONFIG_PERF_EVENTS |
| 1436 | if (tp->flags & TP_FLAG_PROFILE) | 1327 | if (tp->flags & TP_FLAG_PROFILE) |
| 1437 | kretprobe_profile_func(ri, regs); | 1328 | kretprobe_profile_func(ri, regs); |
| 1438 | #endif /* CONFIG_EVENT_PROFILE */ | 1329 | #endif |
| 1439 | return 0; /* We don't tweek kernel, so just return 0 */ | 1330 | return 0; /* We don't tweek kernel, so just return 0 */ |
| 1440 | } | 1331 | } |
| 1441 | 1332 | ||
| @@ -1448,23 +1339,25 @@ static int register_probe_event(struct trace_probe *tp) | |||
| 1448 | if (probe_is_return(tp)) { | 1339 | if (probe_is_return(tp)) { |
| 1449 | tp->event.trace = print_kretprobe_event; | 1340 | tp->event.trace = print_kretprobe_event; |
| 1450 | call->raw_init = probe_event_raw_init; | 1341 | call->raw_init = probe_event_raw_init; |
| 1451 | call->show_format = kretprobe_event_show_format; | ||
| 1452 | call->define_fields = kretprobe_event_define_fields; | 1342 | call->define_fields = kretprobe_event_define_fields; |
| 1453 | } else { | 1343 | } else { |
| 1454 | tp->event.trace = print_kprobe_event; | 1344 | tp->event.trace = print_kprobe_event; |
| 1455 | call->raw_init = probe_event_raw_init; | 1345 | call->raw_init = probe_event_raw_init; |
| 1456 | call->show_format = kprobe_event_show_format; | ||
| 1457 | call->define_fields = kprobe_event_define_fields; | 1346 | call->define_fields = kprobe_event_define_fields; |
| 1458 | } | 1347 | } |
| 1348 | if (set_print_fmt(tp) < 0) | ||
| 1349 | return -ENOMEM; | ||
| 1459 | call->event = &tp->event; | 1350 | call->event = &tp->event; |
| 1460 | call->id = register_ftrace_event(&tp->event); | 1351 | call->id = register_ftrace_event(&tp->event); |
| 1461 | if (!call->id) | 1352 | if (!call->id) { |
| 1353 | kfree(call->print_fmt); | ||
| 1462 | return -ENODEV; | 1354 | return -ENODEV; |
| 1355 | } | ||
| 1463 | call->enabled = 0; | 1356 | call->enabled = 0; |
| 1464 | call->regfunc = probe_event_enable; | 1357 | call->regfunc = probe_event_enable; |
| 1465 | call->unregfunc = probe_event_disable; | 1358 | call->unregfunc = probe_event_disable; |
| 1466 | 1359 | ||
| 1467 | #ifdef CONFIG_EVENT_PROFILE | 1360 | #ifdef CONFIG_PERF_EVENTS |
| 1468 | call->profile_enable = probe_profile_enable; | 1361 | call->profile_enable = probe_profile_enable; |
| 1469 | call->profile_disable = probe_profile_disable; | 1362 | call->profile_disable = probe_profile_disable; |
| 1470 | #endif | 1363 | #endif |
| @@ -1472,6 +1365,7 @@ static int register_probe_event(struct trace_probe *tp) | |||
| 1472 | ret = trace_add_event_call(call); | 1365 | ret = trace_add_event_call(call); |
| 1473 | if (ret) { | 1366 | if (ret) { |
| 1474 | pr_info("Failed to register kprobe event: %s\n", call->name); | 1367 | pr_info("Failed to register kprobe event: %s\n", call->name); |
| 1368 | kfree(call->print_fmt); | ||
| 1475 | unregister_ftrace_event(&tp->event); | 1369 | unregister_ftrace_event(&tp->event); |
| 1476 | } | 1370 | } |
| 1477 | return ret; | 1371 | return ret; |
| @@ -1481,6 +1375,7 @@ static void unregister_probe_event(struct trace_probe *tp) | |||
| 1481 | { | 1375 | { |
| 1482 | /* tp->event is unregistered in trace_remove_event_call() */ | 1376 | /* tp->event is unregistered in trace_remove_event_call() */ |
| 1483 | trace_remove_event_call(&tp->call); | 1377 | trace_remove_event_call(&tp->call); |
| 1378 | kfree(tp->call.print_fmt); | ||
| 1484 | } | 1379 | } |
| 1485 | 1380 | ||
| 1486 | /* Make a debugfs interface for controling probe points */ | 1381 | /* Make a debugfs interface for controling probe points */ |
| @@ -1523,28 +1418,67 @@ static int kprobe_trace_selftest_target(int a1, int a2, int a3, | |||
| 1523 | 1418 | ||
| 1524 | static __init int kprobe_trace_self_tests_init(void) | 1419 | static __init int kprobe_trace_self_tests_init(void) |
| 1525 | { | 1420 | { |
| 1526 | int ret; | 1421 | int ret, warn = 0; |
| 1527 | int (*target)(int, int, int, int, int, int); | 1422 | int (*target)(int, int, int, int, int, int); |
| 1423 | struct trace_probe *tp; | ||
| 1528 | 1424 | ||
| 1529 | target = kprobe_trace_selftest_target; | 1425 | target = kprobe_trace_selftest_target; |
| 1530 | 1426 | ||
| 1531 | pr_info("Testing kprobe tracing: "); | 1427 | pr_info("Testing kprobe tracing: "); |
| 1532 | 1428 | ||
| 1533 | ret = command_trace_probe("p:testprobe kprobe_trace_selftest_target " | 1429 | ret = command_trace_probe("p:testprobe kprobe_trace_selftest_target " |
| 1534 | "$arg1 $arg2 $arg3 $arg4 $stack $stack0"); | 1430 | "$stack $stack0 +0($stack)"); |
| 1535 | if (WARN_ON_ONCE(ret)) | 1431 | if (WARN_ON_ONCE(ret)) { |
| 1536 | pr_warning("error enabling function entry\n"); | 1432 | pr_warning("error on probing function entry.\n"); |
| 1433 | warn++; | ||
| 1434 | } else { | ||
| 1435 | /* Enable trace point */ | ||
| 1436 | tp = find_probe_event("testprobe", KPROBE_EVENT_SYSTEM); | ||
| 1437 | if (WARN_ON_ONCE(tp == NULL)) { | ||
| 1438 | pr_warning("error on getting new probe.\n"); | ||
| 1439 | warn++; | ||
| 1440 | } else | ||
| 1441 | probe_event_enable(&tp->call); | ||
| 1442 | } | ||
| 1537 | 1443 | ||
| 1538 | ret = command_trace_probe("r:testprobe2 kprobe_trace_selftest_target " | 1444 | ret = command_trace_probe("r:testprobe2 kprobe_trace_selftest_target " |
| 1539 | "$retval"); | 1445 | "$retval"); |
| 1540 | if (WARN_ON_ONCE(ret)) | 1446 | if (WARN_ON_ONCE(ret)) { |
| 1541 | pr_warning("error enabling function return\n"); | 1447 | pr_warning("error on probing function return.\n"); |
| 1448 | warn++; | ||
| 1449 | } else { | ||
| 1450 | /* Enable trace point */ | ||
| 1451 | tp = find_probe_event("testprobe2", KPROBE_EVENT_SYSTEM); | ||
| 1452 | if (WARN_ON_ONCE(tp == NULL)) { | ||
| 1453 | pr_warning("error on getting new probe.\n"); | ||
| 1454 | warn++; | ||
| 1455 | } else | ||
| 1456 | probe_event_enable(&tp->call); | ||
| 1457 | } | ||
| 1458 | |||
| 1459 | if (warn) | ||
| 1460 | goto end; | ||
| 1542 | 1461 | ||
| 1543 | ret = target(1, 2, 3, 4, 5, 6); | 1462 | ret = target(1, 2, 3, 4, 5, 6); |
| 1544 | 1463 | ||
| 1545 | cleanup_all_probes(); | 1464 | ret = command_trace_probe("-:testprobe"); |
| 1465 | if (WARN_ON_ONCE(ret)) { | ||
| 1466 | pr_warning("error on deleting a probe.\n"); | ||
| 1467 | warn++; | ||
| 1468 | } | ||
| 1546 | 1469 | ||
| 1547 | pr_cont("OK\n"); | 1470 | ret = command_trace_probe("-:testprobe2"); |
| 1471 | if (WARN_ON_ONCE(ret)) { | ||
| 1472 | pr_warning("error on deleting a probe.\n"); | ||
| 1473 | warn++; | ||
| 1474 | } | ||
| 1475 | |||
| 1476 | end: | ||
| 1477 | cleanup_all_probes(); | ||
| 1478 | if (warn) | ||
| 1479 | pr_cont("NG: Some tests are failed. Please check them.\n"); | ||
| 1480 | else | ||
| 1481 | pr_cont("OK\n"); | ||
| 1548 | return 0; | 1482 | return 0; |
| 1549 | } | 1483 | } |
| 1550 | 1484 | ||
