Pull kprobes updates from Masami Hiramatsu: - Skip negative return code check for snprintf in eprobe - Add recursive call test cases for kprobe unit test - Add 'char' type to probe events to show it as the character instead of value - Update kselftest kprobe-event testcase to ignore '__pfx_' symbols - Fix kselftest to check filter on eprobe event correctly - Add filter on eprobe to the README file in tracefs - Fix optprobes to check whether there is 'under unoptimizing' optprobe when optimizing another kprobe correctly - Fix optprobe to check whether there is 'under unoptimizing' optprobe when fetching the original instruction correctly - Fix optprobe to free 'forcibly unoptimized' optprobe correctly * tag 'probes-v6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: tracing/eprobe: no need to check for negative ret value for snprintf test_kprobes: Add recursed kprobe test case tracing/probe: add a char type to show the character value of traced arguments selftests/ftrace: Fix probepoint testcase to ignore __pfx_* symbols selftests/ftrace: Fix eprobe syntax test case to check filter support tracing/eprobe: Fix to add filter on eprobe description in README file x86/kprobes: Fix arch_check_optimized_kprobe check within optimized_kprobe range x86/kprobes: Fix __recover_optprobed_insn check optimizing logic kprobes: Fix to handle forcibly unoptimized kprobes on freeing_list
Showing the changes to kernel (5 of 12 files). Show all
Unified · Split
| @@ -458,7 +458,7 @@ static inline int kprobe_optready(struct kprobe *p) · 457 unmodified lines | ||
| 458 | 458 | } |
| 459 | 459 | |
| 460 | 460 | /* Return true if the kprobe is disarmed. Note: p must be on hash list */ |
| 461 | −static inline bool kprobe_disarmed(struct kprobe *p) | |
| 461 | +bool kprobe_disarmed(struct kprobe *p) | |
| 462 | 462 | { |
| 463 | 463 | struct optimized_kprobe *op; |
| 464 | 464 | |
| @@ -555,17 +555,15 @@ static void do_unoptimize_kprobes(void) · 90 unmodified lines | ||
| 555 | 555 | /* See comment in do_optimize_kprobes() */ |
| 556 | 556 | lockdep_assert_cpus_held(); |
| 557 | 557 | |
| 558 | − /* Unoptimization must be done anytime */ | |
| 559 | − if (list_empty(&unoptimizing_list)) | |
| 560 | − return; | |
| 558 | + if (!list_empty(&unoptimizing_list)) | |
| 559 | + arch_unoptimize_kprobes(&unoptimizing_list, &freeing_list); | |
| 561 | 560 | |
| 562 | − arch_unoptimize_kprobes(&unoptimizing_list, &freeing_list); | |
| 563 | − /* Loop on 'freeing_list' for disarming */ | |
| 561 | + /* Loop on 'freeing_list' for disarming and removing from kprobe hash list */ | |
| 564 | 562 | list_for_each_entry_safe(op, tmp, &freeing_list, list) { |
| 565 | 563 | /* Switching from detour code to origin */ |
| 566 | 564 | op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED; |
| 567 | − /* Disarm probes if marked disabled */ | |
| 568 | − if (kprobe_disabled(&op->kp)) | |
| 565 | + /* Disarm probes if marked disabled and not gone */ | |
| 566 | + if (kprobe_disabled(&op->kp) && !kprobe_gone(&op->kp)) | |
| 569 | 567 | arch_disarm_kprobe(&op->kp); |
| 570 | 568 | if (kprobe_unused(&op->kp)) { |
| 571 | 569 | /* |
| @@ -662,7 +660,7 @@ void wait_for_kprobe_optimizer(void) · 90 unmodified lines | ||
| 662 | 660 | mutex_unlock(&kprobe_mutex); |
| 663 | 661 | } |
| 664 | 662 | |
| 665 | −static bool optprobe_queued_unopt(struct optimized_kprobe *op) | |
| 663 | +bool optprobe_queued_unopt(struct optimized_kprobe *op) | |
| 666 | 664 | { |
| 667 | 665 | struct optimized_kprobe *_op; |
| 668 | 666 | |
| @@ -797,14 +795,13 @@ static void kill_optimized_kprobe(struct kprobe *p) · 128 unmodified lines | ||
| 797 | 795 | op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED; |
| 798 | 796 | |
| 799 | 797 | if (kprobe_unused(p)) { |
| 800 | − /* Enqueue if it is unused */ | |
| 801 | − list_add(&op->list, &freeing_list); | |
| 802 | 798 | /* |
| 803 | − * Remove unused probes from the hash list. After waiting | |
| 804 | − * for synchronization, this probe is reclaimed. | |
| 805 | − * (reclaiming is done by do_free_cleaned_kprobes().) | |
| 799 | + * Unused kprobe is on unoptimizing or freeing list. We move it | |
| 800 | + * to freeing_list and let the kprobe_optimizer() remove it from | |
| 801 | + * the kprobe hash list and free it. | |
| 806 | 802 | */ |
| 807 | − hlist_del_rcu(&op->kp.hlist); | |
| 803 | + if (optprobe_queued_unopt(op)) | |
| 804 | + list_move(&op->list, &freeing_list); | |
| 808 | 805 | } |
| 809 | 806 | |
| 810 | 807 | /* Don't touch the code, because it is already freed. */ |
| @@ -5646,7 +5646,7 @@ static const char readme_msg[] = · 5645 unmodified lines | ||
| 5646 | 5646 | #ifdef CONFIG_HIST_TRIGGERS |
| 5647 | 5647 | "\t s:[synthetic/]<event> <field> [<field>]\n" |
| 5648 | 5648 | #endif |
| 5649 | − "\t e[:[<group>/][<event>]] <attached-group>.<attached-event> [<args>]\n" | |
| 5649 | + "\t e[:[<group>/][<event>]] <attached-group>.<attached-event> [<args>] [if <filter>]\n" | |
| 5650 | 5650 | "\t -:[<group>/][<event>]\n" |
| 5651 | 5651 | #ifdef CONFIG_KPROBE_EVENTS |
| 5652 | 5652 | "\t place: [<module>:]<symbol>[+<offset>]|<memaddr>\n" |
| @@ -5663,7 +5663,7 @@ static const char readme_msg[] = · 10 unmodified lines | ||
| 5663 | 5663 | "\t $stack<index>, $stack, $retval, $comm,\n" |
| 5664 | 5664 | #endif |
| 5665 | 5665 | "\t +|-[u]<offset>(<fetcharg>), \\imm-value, \\\"imm-string\"\n" |
| 5666 | − "\t type: s8/16/32/64, u8/16/32/64, x8/16/32/64, string, symbol,\n" | |
| 5666 | + "\t type: s8/16/32/64, u8/16/32/64, x8/16/32/64, char, string, symbol,\n" | |
| 5667 | 5667 | "\t b<bit-width>@<bit-offset>/<container-size>, ustring,\n" |
| 5668 | 5668 | "\t symstr, <type>\\[<array-size>\\]\n" |
| 5669 | 5669 | #ifdef CONFIG_HIST_TRIGGERS |
| @@ -923,17 +923,13 @@ static int trace_eprobe_parse_filter(struct trace_eprobe *ep, int argc, const ch · 922 unmodified lines | ||
| 923 | 923 | |
| 924 | 924 | p = ep->filter_str; |
| 925 | 925 | for (i = 0; i < argc; i++) { |
| 926 | − ret = snprintf(p, len, "%s ", argv[i]); | |
| 927 | − if (ret < 0) | |
| 928 | − goto error; | |
| 929 | − if (ret > len) { | |
| 930 | − ret = -E2BIG; | |
| 931 | − goto error; | |
| 932 | − } | |
| 926 | + if (i) | |
| 927 | + ret = snprintf(p, len, " %s", argv[i]); | |
| 928 | + else | |
| 929 | + ret = snprintf(p, len, "%s", argv[i]); | |
| 933 | 930 | p += ret; |
| 934 | 931 | len -= ret; |
| 935 | 932 | } |
| 936 | − p[-1] = '\0'; | |
| 937 | 933 | |
| 938 | 934 | /* |
| 939 | 935 | * Ensure the filter string can be parsed correctly. Note, this |
| @@ -50,6 +50,7 @@ DEFINE_BASIC_PRINT_TYPE_FUNC(x8, u8, "0x%x") · 49 unmodified lines | ||
| 50 | 50 | DEFINE_BASIC_PRINT_TYPE_FUNC(x16, u16, "0x%x") |
| 51 | 51 | DEFINE_BASIC_PRINT_TYPE_FUNC(x32, u32, "0x%x") |
| 52 | 52 | DEFINE_BASIC_PRINT_TYPE_FUNC(x64, u64, "0x%Lx") |
| 53 | +DEFINE_BASIC_PRINT_TYPE_FUNC(char, u8, "'%c'") | |
| 53 | 54 | |
| 54 | 55 | int PRINT_TYPE_FUNC_NAME(symbol)(struct trace_seq *s, void *data, void *ent) |
| 55 | 56 | { |
| @@ -95,6 +96,7 @@ static const struct fetch_type probe_fetch_types[] = { · 39 unmodified lines | ||
| 95 | 96 | ASSIGN_FETCH_TYPE_ALIAS(x16, u16, u16, 0), |
| 96 | 97 | ASSIGN_FETCH_TYPE_ALIAS(x32, u32, u32, 0), |
| 97 | 98 | ASSIGN_FETCH_TYPE_ALIAS(x64, u64, u64, 0), |
| 99 | + ASSIGN_FETCH_TYPE_ALIAS(char, u8, u8, 0), | |
| 98 | 100 | ASSIGN_FETCH_TYPE_ALIAS(symbol, ADDR_FETCH_TYPE, ADDR_FETCH_TYPE, 0), |
| 99 | 101 | |
| 100 | 102 | ASSIGN_FETCH_TYPE_END |
| @@ -166,6 +166,7 @@ DECLARE_BASIC_PRINT_TYPE_FUNC(x16); · 165 unmodified lines | ||
| 166 | 166 | DECLARE_BASIC_PRINT_TYPE_FUNC(x32); |
| 167 | 167 | DECLARE_BASIC_PRINT_TYPE_FUNC(x64); |
| 168 | 168 | |
| 169 | +DECLARE_BASIC_PRINT_TYPE_FUNC(char); | |
| 169 | 170 | DECLARE_BASIC_PRINT_TYPE_FUNC(string); |
| 170 | 171 | DECLARE_BASIC_PRINT_TYPE_FUNC(symbol); |
| 171 | 172 | |