| @@ -91,11 +91,6 @@ static __kprobes unsigned long fetch_memory(struct pt_regs *regs, void *addr) · 90 unmodified lines |
| 91 | 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 | 94 | static __kprobes unsigned long fetch_retvalue(struct pt_regs *regs, |
| 100 | 95 | void *dummy) |
| 101 | 96 | { |
| @@ -231,9 +226,7 @@ static int probe_arg_string(char *buf, size_t n, struct fetch_func *ff) · 129 unmodified lines |
| 231 | 226 | { |
| 232 | 227 | int ret = -EINVAL; |
| 233 | 228 | |
| 234 | | − if (ff->func == fetch_argument) |
| 235 | | − ret = snprintf(buf, n, "$arg%lu", (unsigned long)ff->data); |
| 236 | | − else if (ff->func == fetch_register) { |
| 229 | + if (ff->func == fetch_register) { |
| 237 | 230 | const char *name; |
| 238 | 231 | name = regs_query_register_name((unsigned int)((long)ff->data)); |
| 239 | 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) · 249 unmodified lines |
| 489 | 482 | } |
| 490 | 483 | } else |
| 491 | 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 | 485 | } else |
| 501 | 486 | ret = -EINVAL; |
| 502 | 487 | return ret; |
| @@ -611,7 +596,6 @@ static int create_trace_probe(int argc, char **argv) · 108 unmodified lines |
| 611 | 596 | * - Add kprobe: p[:[GRP/]EVENT] KSYM[+OFFS]|KADDR [FETCHARGS] |
| 612 | 597 | * - Add kretprobe: r[:[GRP/]EVENT] KSYM[+0] [FETCHARGS] |
| 613 | 598 | * Fetch args: |
| 614 | | − * $argN : fetch Nth of function argument. (N:0-) |
| 615 | 599 | * $retval : fetch return value |
| 616 | 600 | * $stack : fetch stack address |
| 617 | 601 | * $stackN : fetch Nth of stack (N:0-) |
| @@ -958,7 +942,7 @@ static const struct file_operations kprobe_profile_ops = { · 340 unmodified lines |
| 958 | 942 | }; |
| 959 | 943 | |
| 960 | 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 | 947 | struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp); |
| 964 | 948 | struct kprobe_trace_entry *entry; |
| @@ -978,7 +962,7 @@ static __kprobes int kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) · 13 unmodified lines |
| 978 | 962 | event = trace_current_buffer_lock_reserve(&buffer, call->id, size, |
| 979 | 963 | irq_flags, pc); |
| 980 | 964 | if (!event) |
| 981 | | − return 0; |
| 965 | + return; |
| 982 | 966 | |
| 983 | 967 | entry = ring_buffer_event_data(event); |
| 984 | 968 | entry->nargs = tp->nr_args; |
| @@ -988,11 +972,10 @@ static __kprobes int kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) · 3 unmodified lines |
| 988 | 972 | |
| 989 | 973 | if (!filter_current_check_discard(buffer, call, entry, event)) |
| 990 | 974 | trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc); |
| 991 | | − return 0; |
| 992 | 975 | } |
| 993 | 976 | |
| 994 | 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 | 979 | struct pt_regs *regs) |
| 997 | 980 | { |
| 998 | 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, · 12 unmodified lines |
| 1011 | 994 | event = trace_current_buffer_lock_reserve(&buffer, call->id, size, |
| 1012 | 995 | irq_flags, pc); |
| 1013 | 996 | if (!event) |
| 1014 | | − return 0; |
| 997 | + return; |
| 1015 | 998 | |
| 1016 | 999 | entry = ring_buffer_event_data(event); |
| 1017 | 1000 | entry->nargs = tp->nr_args; |
| @@ -1022,8 +1005,6 @@ static __kprobes int kretprobe_trace_func(struct kretprobe_instance *ri, · 4 unmodified lines |
| 1022 | 1005 | |
| 1023 | 1006 | if (!filter_current_check_discard(buffer, call, entry, event)) |
| 1024 | 1007 | trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc); |
| 1025 | | − |
| 1026 | | − return 0; |
| 1027 | 1008 | } |
| 1028 | 1009 | |
| 1029 | 1010 | /* Event entry printers */ |
| @@ -1230,137 +1211,67 @@ static int set_print_fmt(struct trace_probe *tp) · 200 unmodified lines |
| 1230 | 1211 | return 0; |
| 1231 | 1212 | } |
| 1232 | 1213 | |
| 1233 | | −#ifdef CONFIG_EVENT_PROFILE |
| 1214 | +#ifdef CONFIG_PERF_EVENTS |
| 1234 | 1215 | |
| 1235 | 1216 | /* Kprobe profile handler */ |
| 1236 | | −static __kprobes int kprobe_profile_func(struct kprobe *kp, |
| 1217 | +static __kprobes void kprobe_profile_func(struct kprobe *kp, |
| 1237 | 1218 | struct pt_regs *regs) |
| 1238 | 1219 | { |
| 1239 | 1220 | struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp); |
| 1240 | 1221 | struct ftrace_event_call *call = &tp->call; |
| 1241 | 1222 | struct kprobe_trace_entry *entry; |
| 1242 | | − struct trace_entry *ent; |
| 1243 | | − int size, __size, i, pc, __cpu; |
| 1223 | + int size, __size, i; |
| 1244 | 1224 | unsigned long irq_flags; |
| 1245 | | − char *trace_buf; |
| 1246 | | − char *raw_data; |
| 1247 | 1225 | int rctx; |
| 1248 | 1226 | |
| 1249 | | − pc = preempt_count(); |
| 1250 | 1227 | __size = SIZEOF_KPROBE_TRACE_ENTRY(tp->nr_args); |
| 1251 | 1228 | size = ALIGN(__size + sizeof(u32), sizeof(u64)); |
| 1252 | 1229 | size -= sizeof(u32); |
| 1253 | 1230 | if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE, |
| 1254 | 1231 | "profile buffer not large enough")) |
| 1255 | | − return 0; |
| 1256 | | − |
| 1257 | | − /* |
| 1258 | | − * Protect the non nmi buffer |
| 1259 | | − * This also protects the rcu read side |
| 1260 | | − */ |
| 1261 | | − local_irq_save(irq_flags); |
| 1232 | + return; |
| 1262 | 1233 | |
| 1263 | | − rctx = perf_swevent_get_recursion_context(); |
| 1264 | | − if (rctx < 0) |
| 1265 | | − goto end_recursion; |
| 1266 | | − |
| 1267 | | − __cpu = smp_processor_id(); |
| 1268 | | − |
| 1269 | | − if (in_nmi()) |
| 1270 | | − trace_buf = rcu_dereference(perf_trace_buf_nmi); |
| 1271 | | − else |
| 1272 | | − trace_buf = rcu_dereference(perf_trace_buf); |
| 1273 | | − |
| 1274 | | − if (!trace_buf) |
| 1275 | | − goto end; |
| 1276 | | − |
| 1277 | | − raw_data = per_cpu_ptr(trace_buf, __cpu); |
| 1278 | | − |
| 1279 | | − /* Zero dead bytes from alignment to avoid buffer leak to userspace */ |
| 1280 | | − *(u64 *)(&raw_data[size - sizeof(u64)]) = 0ULL; |
| 1281 | | − entry = (struct kprobe_trace_entry *)raw_data; |
| 1282 | | − ent = &entry->ent; |
| 1234 | + entry = ftrace_perf_buf_prepare(size, call->id, &rctx, &irq_flags); |
| 1235 | + if (!entry) |
| 1236 | + return; |
| 1283 | 1237 | |
| 1284 | | − tracing_generic_entry_update(ent, irq_flags, pc); |
| 1285 | | − ent->type = call->id; |
| 1286 | 1238 | entry->nargs = tp->nr_args; |
| 1287 | 1239 | entry->ip = (unsigned long)kp->addr; |
| 1288 | 1240 | for (i = 0; i < tp->nr_args; i++) |
| 1289 | 1241 | entry->args[i] = call_fetch(&tp->args[i].fetch, regs); |
| 1290 | | − perf_tp_event(call->id, entry->ip, 1, entry, size); |
| 1291 | 1242 | |
| 1292 | | −end: |
| 1293 | | − perf_swevent_put_recursion_context(rctx); |
| 1294 | | −end_recursion: |
| 1295 | | − local_irq_restore(irq_flags); |
| 1296 | | − |
| 1297 | | − return 0; |
| 1243 | + ftrace_perf_buf_submit(entry, size, rctx, entry->ip, 1, irq_flags); |
| 1298 | 1244 | } |
| 1299 | 1245 | |
| 1300 | 1246 | /* Kretprobe profile handler */ |
| 1301 | | −static __kprobes int kretprobe_profile_func(struct kretprobe_instance *ri, |
| 1247 | +static __kprobes void kretprobe_profile_func(struct kretprobe_instance *ri, |
| 1302 | 1248 | struct pt_regs *regs) |
| 1303 | 1249 | { |
| 1304 | 1250 | struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp); |
| 1305 | 1251 | struct ftrace_event_call *call = &tp->call; |
| 1306 | 1252 | struct kretprobe_trace_entry *entry; |
| 1307 | | − struct trace_entry *ent; |
| 1308 | | − int size, __size, i, pc, __cpu; |
| 1253 | + int size, __size, i; |
| 1309 | 1254 | unsigned long irq_flags; |
| 1310 | | − char *trace_buf; |
| 1311 | | − char *raw_data; |
| 1312 | 1255 | int rctx; |
| 1313 | 1256 | |
| 1314 | | − pc = preempt_count(); |
| 1315 | 1257 | __size = SIZEOF_KRETPROBE_TRACE_ENTRY(tp->nr_args); |
| 1316 | 1258 | size = ALIGN(__size + sizeof(u32), sizeof(u64)); |
| 1317 | 1259 | size -= sizeof(u32); |
| 1318 | 1260 | if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE, |
| 1319 | 1261 | "profile buffer not large enough")) |
| 1320 | | − return 0; |
| 1321 | | − |
| 1322 | | − /* |
| 1323 | | − * Protect the non nmi buffer |
| 1324 | | − * This also protects the rcu read side |
| 1325 | | − */ |
| 1326 | | − local_irq_save(irq_flags); |
| 1327 | | − |
| 1328 | | − rctx = perf_swevent_get_recursion_context(); |
| 1329 | | − if (rctx < 0) |
| 1330 | | − goto end_recursion; |
| 1331 | | − |
| 1332 | | − __cpu = smp_processor_id(); |
| 1333 | | − |
| 1334 | | − if (in_nmi()) |
| 1335 | | − trace_buf = rcu_dereference(perf_trace_buf_nmi); |
| 1336 | | − else |
| 1337 | | − trace_buf = rcu_dereference(perf_trace_buf); |
| 1338 | | − |
| 1339 | | − if (!trace_buf) |
| 1340 | | − goto end; |
| 1341 | | − |
| 1342 | | − raw_data = per_cpu_ptr(trace_buf, __cpu); |
| 1262 | + return; |
| 1343 | 1263 | |
| 1344 | | − /* Zero dead bytes from alignment to avoid buffer leak to userspace */ |
| 1345 | | − *(u64 *)(&raw_data[size - sizeof(u64)]) = 0ULL; |
| 1346 | | − entry = (struct kretprobe_trace_entry *)raw_data; |
| 1347 | | − ent = &entry->ent; |
| 1264 | + entry = ftrace_perf_buf_prepare(size, call->id, &rctx, &irq_flags); |
| 1265 | + if (!entry) |
| 1266 | + return; |
| 1348 | 1267 | |
| 1349 | | − tracing_generic_entry_update(ent, irq_flags, pc); |
| 1350 | | − ent->type = call->id; |
| 1351 | 1268 | entry->nargs = tp->nr_args; |
| 1352 | 1269 | entry->func = (unsigned long)tp->rp.kp.addr; |
| 1353 | 1270 | entry->ret_ip = (unsigned long)ri->ret_addr; |
| 1354 | 1271 | for (i = 0; i < tp->nr_args; i++) |
| 1355 | 1272 | entry->args[i] = call_fetch(&tp->args[i].fetch, regs); |
| 1356 | | − perf_tp_event(call->id, entry->ret_ip, 1, entry, size); |
| 1357 | | − |
| 1358 | | −end: |
| 1359 | | − perf_swevent_put_recursion_context(rctx); |
| 1360 | | −end_recursion: |
| 1361 | | − local_irq_restore(irq_flags); |
| 1362 | 1273 | |
| 1363 | | − return 0; |
| 1274 | + ftrace_perf_buf_submit(entry, size, rctx, entry->ret_ip, 1, irq_flags); |
| 1364 | 1275 | } |
| 1365 | 1276 | |
| 1366 | 1277 | static int probe_profile_enable(struct ftrace_event_call *call) |
| @@ -1388,7 +1299,7 @@ static void probe_profile_disable(struct ftrace_event_call *call) · 21 unmodified lines |
| 1388 | 1299 | disable_kprobe(&tp->rp.kp); |
| 1389 | 1300 | } |
| 1390 | 1301 | } |
| 1391 | | −#endif /* CONFIG_EVENT_PROFILE */ |
| 1302 | +#endif /* CONFIG_PERF_EVENTS */ |
| 1392 | 1303 | |
| 1393 | 1304 | |
| 1394 | 1305 | static __kprobes |
| @@ -1398,10 +1309,10 @@ int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs) · 3 unmodified lines |
| 1398 | 1309 | |
| 1399 | 1310 | if (tp->flags & TP_FLAG_TRACE) |
| 1400 | 1311 | kprobe_trace_func(kp, regs); |
| 1401 | | −#ifdef CONFIG_EVENT_PROFILE |
| 1312 | +#ifdef CONFIG_PERF_EVENTS |
| 1402 | 1313 | if (tp->flags & TP_FLAG_PROFILE) |
| 1403 | 1314 | kprobe_profile_func(kp, regs); |
| 1404 | | −#endif /* CONFIG_EVENT_PROFILE */ |
| 1315 | +#endif |
| 1405 | 1316 | return 0; /* We don't tweek kernel, so just return 0 */ |
| 1406 | 1317 | } |
| 1407 | 1318 | |
| @@ -1412,10 +1323,10 @@ int kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs) · 4 unmodified lines |
| 1412 | 1323 | |
| 1413 | 1324 | if (tp->flags & TP_FLAG_TRACE) |
| 1414 | 1325 | kretprobe_trace_func(ri, regs); |
| 1415 | | −#ifdef CONFIG_EVENT_PROFILE |
| 1326 | +#ifdef CONFIG_PERF_EVENTS |
| 1416 | 1327 | if (tp->flags & TP_FLAG_PROFILE) |
| 1417 | 1328 | kretprobe_profile_func(ri, regs); |
| 1418 | | −#endif /* CONFIG_EVENT_PROFILE */ |
| 1329 | +#endif |
| 1419 | 1330 | return 0; /* We don't tweek kernel, so just return 0 */ |
| 1420 | 1331 | } |
| 1421 | 1332 | |
| @@ -1446,7 +1357,7 @@ static int register_probe_event(struct trace_probe *tp) · 24 unmodified lines |
| 1446 | 1357 | call->regfunc = probe_event_enable; |
| 1447 | 1358 | call->unregfunc = probe_event_disable; |
| 1448 | 1359 | |
| 1449 | | −#ifdef CONFIG_EVENT_PROFILE |
| 1360 | +#ifdef CONFIG_PERF_EVENTS |
| 1450 | 1361 | call->profile_enable = probe_profile_enable; |
| 1451 | 1362 | call->profile_disable = probe_profile_disable; |
| 1452 | 1363 | #endif |
| @@ -1507,28 +1418,67 @@ static int kprobe_trace_selftest_target(int a1, int a2, int a3, · 54 unmodified lines |
| 1507 | 1418 | |
| 1508 | 1419 | static __init int kprobe_trace_self_tests_init(void) |
| 1509 | 1420 | { |
| 1510 | | − int ret; |
| 1421 | + int ret, warn = 0; |
| 1511 | 1422 | int (*target)(int, int, int, int, int, int); |
| 1423 | + struct trace_probe *tp; |
| 1512 | 1424 | |
| 1513 | 1425 | target = kprobe_trace_selftest_target; |
| 1514 | 1426 | |
| 1515 | 1427 | pr_info("Testing kprobe tracing: "); |
| 1516 | 1428 | |
| 1517 | 1429 | ret = command_trace_probe("p:testprobe kprobe_trace_selftest_target " |
| 1518 | | − "$arg1 $arg2 $arg3 $arg4 $stack $stack0"); |
| 1519 | | − if (WARN_ON_ONCE(ret)) |
| 1520 | | − pr_warning("error enabling function entry\n"); |
| 1430 | + "$stack $stack0 +0($stack)"); |
| 1431 | + if (WARN_ON_ONCE(ret)) { |
| 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 | + } |
| 1521 | 1443 | |
| 1522 | 1444 | ret = command_trace_probe("r:testprobe2 kprobe_trace_selftest_target " |
| 1523 | 1445 | "$retval"); |
| 1524 | | − if (WARN_ON_ONCE(ret)) |
| 1525 | | − pr_warning("error enabling function return\n"); |
| 1446 | + if (WARN_ON_ONCE(ret)) { |
| 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; |
| 1526 | 1461 | |
| 1527 | 1462 | ret = target(1, 2, 3, 4, 5, 6); |
| 1528 | 1463 | |
| 1529 | | − 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 | + } |
| 1469 | + |
| 1470 | + ret = command_trace_probe("-:testprobe2"); |
| 1471 | + if (WARN_ON_ONCE(ret)) { |
| 1472 | + pr_warning("error on deleting a probe.\n"); |
| 1473 | + warn++; |
| 1474 | + } |
| 1530 | 1475 | |
| 1531 | | − pr_cont("OK\n"); |
| 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"); |
| 1532 | 1482 | return 0; |
| 1533 | 1483 | } |
| 1534 | 1484 | |