Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fprobe: Use ftrace_regs in fprobe entry handler

This allows fprobes to be available with CONFIG_DYNAMIC_FTRACE_WITH_ARGS
instead of CONFIG_DYNAMIC_FTRACE_WITH_REGS, then we can enable fprobe
on arm64.

Cc: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: Martin KaFai Lau <martin.lau@linux.dev>
Cc: bpf <bpf@vger.kernel.org>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Alan Maguire <alan.maguire@oracle.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Link: https://lore.kernel.org/173518994037.391279.2786805566359674586.stgit@devnote2
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Acked-by: Florent Revest <revest@chromium.org>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>

authored by

Masami Hiramatsu (Google) and committed by
Steven Rostedt (Google)
46bc0823 2ca8c112

+23 -12
+1 -1
include/linux/fprobe.h
··· 10 10 struct fprobe; 11 11 12 12 typedef int (*fprobe_entry_cb)(struct fprobe *fp, unsigned long entry_ip, 13 - unsigned long ret_ip, struct pt_regs *regs, 13 + unsigned long ret_ip, struct ftrace_regs *regs, 14 14 void *entry_data); 15 15 16 16 typedef void (*fprobe_exit_cb)(struct fprobe *fp, unsigned long entry_ip,
+2 -1
kernel/trace/Kconfig
··· 297 297 config FPROBE 298 298 bool "Kernel Function Probe (fprobe)" 299 299 depends on FUNCTION_TRACER 300 - depends on DYNAMIC_FTRACE_WITH_REGS 300 + depends on DYNAMIC_FTRACE_WITH_REGS || DYNAMIC_FTRACE_WITH_ARGS 301 301 depends on HAVE_RETHOOK 302 302 select RETHOOK 303 303 default n ··· 682 682 select TRACING 683 683 select PROBE_EVENTS 684 684 select DYNAMIC_EVENTS 685 + depends on DYNAMIC_FTRACE_WITH_REGS 685 686 default y 686 687 help 687 688 This allows user to add tracing events on the function entry and
+7 -3
kernel/trace/bpf_trace.c
··· 2561 2561 void *data; 2562 2562 }; 2563 2563 2564 - #ifdef CONFIG_FPROBE 2564 + #if defined(CONFIG_FPROBE) && defined(CONFIG_DYNAMIC_FTRACE_WITH_REGS) 2565 2565 struct bpf_kprobe_multi_link { 2566 2566 struct bpf_link link; 2567 2567 struct fprobe fp; ··· 2813 2813 2814 2814 static int 2815 2815 kprobe_multi_link_handler(struct fprobe *fp, unsigned long fentry_ip, 2816 - unsigned long ret_ip, struct pt_regs *regs, 2816 + unsigned long ret_ip, struct ftrace_regs *fregs, 2817 2817 void *data) 2818 2818 { 2819 + struct pt_regs *regs = ftrace_get_regs(fregs); 2819 2820 struct bpf_kprobe_multi_link *link; 2820 2821 int err; 2822 + 2823 + if (!regs) 2824 + return 0; 2821 2825 2822 2826 link = container_of(fp, struct bpf_kprobe_multi_link, fp); 2823 2827 err = kprobe_multi_link_prog_run(link, get_entry_ip(fentry_ip), regs, false, data); ··· 3097 3093 kvfree(cookies); 3098 3094 return err; 3099 3095 } 3100 - #else /* !CONFIG_FPROBE */ 3096 + #else /* !CONFIG_FPROBE || !CONFIG_DYNAMIC_FTRACE_WITH_REGS */ 3101 3097 int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog) 3102 3098 { 3103 3099 return -EOPNOTSUPP;
+2 -1
kernel/trace/fprobe.c
··· 46 46 } 47 47 48 48 if (fp->entry_handler) 49 - ret = fp->entry_handler(fp, ip, parent_ip, ftrace_get_regs(fregs), entry_data); 49 + ret = fp->entry_handler(fp, ip, parent_ip, fregs, entry_data); 50 50 51 51 /* If entry_handler returns !0, nmissed is not counted. */ 52 52 if (rh) { ··· 182 182 fp->ops.func = fprobe_kprobe_handler; 183 183 else 184 184 fp->ops.func = fprobe_handler; 185 + 185 186 fp->ops.flags |= FTRACE_OPS_FL_SAVE_REGS; 186 187 } 187 188
+8 -3
kernel/trace/trace_fprobe.c
··· 217 217 218 218 /* function exit handler */ 219 219 static int trace_fprobe_entry_handler(struct fprobe *fp, unsigned long entry_ip, 220 - unsigned long ret_ip, struct pt_regs *regs, 220 + unsigned long ret_ip, struct ftrace_regs *fregs, 221 221 void *entry_data) 222 222 { 223 223 struct trace_fprobe *tf = container_of(fp, struct trace_fprobe, fp); 224 + struct pt_regs *regs = ftrace_get_regs(fregs); 224 225 225 - if (tf->tp.entry_arg) 226 + if (regs && tf->tp.entry_arg) 226 227 store_trace_entry_data(entry_data, &tf->tp, regs); 227 228 228 229 return 0; ··· 340 339 #endif /* CONFIG_PERF_EVENTS */ 341 340 342 341 static int fentry_dispatcher(struct fprobe *fp, unsigned long entry_ip, 343 - unsigned long ret_ip, struct pt_regs *regs, 342 + unsigned long ret_ip, struct ftrace_regs *fregs, 344 343 void *entry_data) 345 344 { 346 345 struct trace_fprobe *tf = container_of(fp, struct trace_fprobe, fp); 346 + struct pt_regs *regs = ftrace_get_regs(fregs); 347 347 int ret = 0; 348 + 349 + if (!regs) 350 + return 0; 348 351 349 352 if (trace_probe_test_flag(&tf->tp, TP_FLAG_TRACE)) 350 353 fentry_trace_func(tf, entry_ip, regs);
+2 -2
lib/test_fprobe.c
··· 40 40 41 41 static notrace int fp_entry_handler(struct fprobe *fp, unsigned long ip, 42 42 unsigned long ret_ip, 43 - struct pt_regs *regs, void *data) 43 + struct ftrace_regs *fregs, void *data) 44 44 { 45 45 KUNIT_EXPECT_FALSE(current_test, preemptible()); 46 46 /* This can be called on the fprobe_selftest_target and the fprobe_selftest_target2 */ ··· 81 81 82 82 static notrace int nest_entry_handler(struct fprobe *fp, unsigned long ip, 83 83 unsigned long ret_ip, 84 - struct pt_regs *regs, void *data) 84 + struct ftrace_regs *fregs, void *data) 85 85 { 86 86 KUNIT_EXPECT_FALSE(current_test, preemptible()); 87 87 return 0;
+1 -1
samples/fprobe/fprobe_example.c
··· 50 50 51 51 static int sample_entry_handler(struct fprobe *fp, unsigned long ip, 52 52 unsigned long ret_ip, 53 - struct pt_regs *regs, void *data) 53 + struct ftrace_regs *fregs, void *data) 54 54 { 55 55 if (use_trace) 56 56 /*