Message ID | 170290538307.220107.14964448383069008953.stgit@devnote2 (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | tracing: fprobe: function_graph: Multi-function graph and fprobe on fgraph | expand |
On Mon, Dec 18, 2023 at 10:16:23PM +0900, Masami Hiramatsu (Google) wrote: > From: Masami Hiramatsu (Google) <mhiramat@kernel.org> > > 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. > > Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> > Acked-by: Florent Revest <revest@chromium.org> this change breaks kprobe multi bpf tests (crash below), which are partially fixed by [1] later on, but I think we have to keep bisecting crash free it looks like the rethook will get wrong pointer.. I'm still trying to digest the whole thing, so I might have some updates later ;-) jirka [1] fprobe: Rewrite fprobe on function-graph tracer --- Dec 19 13:50:04 qemu kernel: BUG: kernel NULL pointer dereference, address: 0000000000000098 Dec 19 13:50:04 qemu kernel: #PF: supervisor read access in kernel mode Dec 19 13:50:04 qemu kernel: #PF: error_code(0x0000) - not-present page Dec 19 13:50:04 qemu kernel: PGD 10955f067 P4D 10955f067 PUD 103113067 PMD 0 Dec 19 13:50:04 qemu kernel: Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC KASAN NOPTI Dec 19 13:50:04 qemu kernel: CPU: 1 PID: 747 Comm: test_progs Tainted: G B OE 6.7.0-rc3+ #194 85bc8297edbc7f21acfc743dabbd52cac073a6bf Dec 19 13:50:04 qemu kernel: Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-1.fc38 04/01/2014 Dec 19 13:50:04 qemu kernel: RIP: 0010:arch_rethook_prepare+0x18/0x60 Dec 19 13:50:04 qemu kernel: Code: 1f 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 41 55 41 54 55 48 89 f5 53 48 89 fb 48 8d be 98 00 00 00 e8 68 8f 59 > Dec 19 13:50:04 qemu kernel: RSP: 0018:ffff888125f97a88 EFLAGS: 00010286 Dec 19 13:50:04 qemu kernel: RAX: 0000000000000001 RBX: ffff88818a231410 RCX: ffffffff812190b6 Dec 19 13:50:04 qemu kernel: RDX: fffffbfff0c42e95 RSI: 0000000000000008 RDI: ffffffff862174a0 Dec 19 13:50:04 qemu kernel: RBP: 0000000000000000 R08: 0000000000000001 R09: fffffbfff0c42e94 Dec 19 13:50:04 qemu kernel: R10: ffffffff862174a7 R11: 0000000000000000 R12: ffff88818a231420 Dec 19 13:50:04 qemu kernel: R13: ffffffff8283ee8e R14: ffff88818a231410 R15: fffffffffffffff7 Dec 19 13:50:04 qemu kernel: FS: 00007ff8a16cfd00(0000) GS:ffff88842c600000(0000) knlGS:0000000000000000 Dec 19 13:50:05 qemu kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 Dec 19 13:50:05 qemu kernel: CR2: 0000000000000098 CR3: 000000010633c005 CR4: 0000000000770ef0 Dec 19 13:50:05 qemu kernel: PKRU: 55555554 Dec 19 13:50:05 qemu kernel: Call Trace: Dec 19 13:50:05 qemu kernel: <TASK> Dec 19 13:50:05 qemu kernel: ? __die+0x1f/0x70 Dec 19 13:50:05 qemu kernel: ? page_fault_oops+0x215/0x620 Dec 19 13:50:05 qemu kernel: ? rcu_is_watching+0x34/0x60 Dec 19 13:50:05 qemu kernel: ? __pfx_page_fault_oops+0x10/0x10 Dec 19 13:50:05 qemu kernel: ? asm_sysvec_apic_timer_interrupt+0x16/0x20 Dec 19 13:50:05 qemu kernel: ? do_user_addr_fault+0x4b3/0x910 Dec 19 13:50:05 qemu kernel: ? exc_page_fault+0x77/0x130 Dec 19 13:50:05 qemu kernel: ? asm_exc_page_fault+0x22/0x30 Dec 19 13:50:05 qemu kernel: ? bpf_prog_test_run_tracing+0x1ce/0x2d0 Dec 19 13:50:05 qemu kernel: ? add_taint+0x26/0x90 Dec 19 13:50:05 qemu kernel: ? arch_rethook_prepare+0x18/0x60 Dec 19 13:50:05 qemu kernel: ? arch_rethook_prepare+0x18/0x60 Dec 19 13:50:05 qemu kernel: ? bpf_prog_test_run_tracing+0x1ce/0x2d0 Dec 19 13:50:05 qemu kernel: rethook_hook+0x1e/0x50 Dec 19 13:50:05 qemu kernel: ? __pfx_bpf_fentry_test1+0x10/0x10 Dec 19 13:50:05 qemu kernel: ? bpf_prog_test_run_tracing+0x1ce/0x2d0 Dec 19 13:50:05 qemu kernel: fprobe_handler+0x1ca/0x350 Dec 19 13:50:05 qemu kernel: ? __pfx_bpf_fentry_test1+0x10/0x10 Dec 19 13:50:05 qemu kernel: arch_ftrace_ops_list_func+0x143/0x2e0 Dec 19 13:50:05 qemu kernel: ? bpf_prog_test_run_tracing+0x1ce/0x2d0 Dec 19 13:50:05 qemu kernel: ftrace_call+0x5/0x44 Dec 19 13:50:05 qemu kernel: ? __pfx_lock_release+0x10/0x10 Dec 19 13:50:05 qemu kernel: ? rcu_is_watching+0x34/0x60 Dec 19 13:50:05 qemu kernel: ? bpf_prog_test_run_tracing+0xcd/0x2d0 Dec 19 13:50:05 qemu kernel: ? bpf_fentry_test1+0x5/0x10 Dec 19 13:50:05 qemu kernel: ? rcu_is_watching+0x34/0x60 Dec 19 13:50:05 qemu kernel: bpf_fentry_test1+0x5/0x10 Dec 19 13:50:05 qemu kernel: bpf_prog_test_run_tracing+0x1ce/0x2d0 Dec 19 13:50:05 qemu kernel: ? __pfx_lock_release+0x10/0x10 Dec 19 13:50:05 qemu kernel: ? __pfx_bpf_prog_test_run_tracing+0x10/0x10 Dec 19 13:50:05 qemu kernel: ? __pfx_lock_release+0x10/0x10 Dec 19 13:50:05 qemu kernel: ? __fget_light+0xdf/0x100 Dec 19 13:50:05 qemu kernel: ? __bpf_prog_get+0x107/0x150 Dec 19 13:50:05 qemu kernel: __sys_bpf+0x552/0x2ef0 Dec 19 13:50:05 qemu kernel: ? rcu_is_watching+0x34/0x60 Dec 19 13:50:05 qemu kernel: ? __pfx___sys_bpf+0x10/0x10 Dec 19 13:50:05 qemu kernel: ? __pfx_lock_release+0x10/0x10 Dec 19 13:50:05 qemu kernel: ? vfs_write+0x1fa/0x740 Dec 19 13:50:05 qemu kernel: ? rcu_is_watching+0x34/0x60 Dec 19 13:50:05 qemu kernel: ? rcu_is_watching+0x34/0x60 Dec 19 13:50:05 qemu kernel: ? lockdep_hardirqs_on_prepare+0xe/0x250 Dec 19 13:50:05 qemu kernel: ? seqcount_lockdep_reader_access.constprop.0+0x105/0x120 Dec 19 13:50:05 qemu kernel: ? seqcount_lockdep_reader_access.constprop.0+0xb2/0x120 Dec 19 13:50:05 qemu kernel: __x64_sys_bpf+0x44/0x60 Dec 19 13:50:05 qemu kernel: do_syscall_64+0x3f/0xf0 Dec 19 13:50:05 qemu kernel: entry_SYSCALL_64_after_hwframe+0x6e/0x76 Dec 19 13:50:05 qemu kernel: RIP: 0033:0x7ff8a1897b4d Dec 19 13:50:05 qemu kernel: Code: c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f > Dec 19 13:50:05 qemu kernel: RSP: 002b:00007fff34f7d158 EFLAGS: 00000206 ORIG_RAX: 0000000000000141 Dec 19 13:50:05 qemu kernel: RAX: ffffffffffffffda RBX: 00007ff8a19aa000 RCX: 00007ff8a1897b4d Dec 19 13:50:05 qemu kernel: RDX: 0000000000000050 RSI: 00007fff34f7d190 RDI: 000000000000000a Dec 19 13:50:05 qemu kernel: RBP: 00007fff34f7d170 R08: 0000000000000000 R09: 00007fff34f7d190 Dec 19 13:50:05 qemu kernel: R10: 0000000000000064 R11: 0000000000000206 R12: 0000000000000004 Dec 19 13:50:05 qemu kernel: R13: 0000000000000000 R14: 00007ff8a19df000 R15: 0000000000e56db0 Dec 19 13:50:05 qemu kernel: </TASK> Dec 19 13:50:05 qemu kernel: Modules linked in: bpf_testmod(OE) intel_rapl_msr intel_rapl_common crct10dif_pclmul crc32_pclmul crc32c_intel ghash_clmulni_inte> Dec 19 13:50:05 qemu kernel: CR2: 0000000000000098 Dec 19 13:50:05 qemu kernel: ---[ end trace 0000000000000000 ]---
On Mon, Dec 18, 2023 at 10:16:23PM +0900, Masami Hiramatsu (Google) wrote: SNIP > diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c > index 84e8a0f6e4e0..d3f8745d8ead 100644 > --- a/kernel/trace/bpf_trace.c > +++ b/kernel/trace/bpf_trace.c > @@ -2503,7 +2503,7 @@ static int __init bpf_event_init(void) > fs_initcall(bpf_event_init); > #endif /* CONFIG_MODULES */ > > -#ifdef CONFIG_FPROBE > +#if defined(CONFIG_FPROBE) && defined(CONFIG_DYNAMIC_FTRACE_WITH_REGS) > struct bpf_kprobe_multi_link { > struct bpf_link link; > struct fprobe fp; > @@ -2733,10 +2733,14 @@ kprobe_multi_link_prog_run(struct bpf_kprobe_multi_link *link, > > static int > kprobe_multi_link_handler(struct fprobe *fp, unsigned long fentry_ip, > - unsigned long ret_ip, struct pt_regs *regs, > + unsigned long ret_ip, struct ftrace_regs *fregs, > void *data) > { > struct bpf_kprobe_multi_link *link; > + struct pt_regs *regs = ftrace_get_regs(fregs); > + > + if (!regs) > + return 0; > > link = container_of(fp, struct bpf_kprobe_multi_link, fp); > kprobe_multi_link_prog_run(link, get_entry_ip(fentry_ip), regs); > @@ -3008,7 +3012,7 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr > kvfree(cookies); > return err; > } > -#else /* !CONFIG_FPROBE */ > +#else /* !CONFIG_FPROBE || !CONFIG_DYNAMIC_FTRACE_WITH_REGS */ > int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog) > { > return -EOPNOTSUPP; > diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c > index 6cd2a4e3afb8..f12569494d8a 100644 > --- a/kernel/trace/fprobe.c > +++ b/kernel/trace/fprobe.c > @@ -46,7 +46,7 @@ static inline void __fprobe_handler(unsigned long ip, unsigned long parent_ip, > } > > if (fp->entry_handler) > - ret = fp->entry_handler(fp, ip, parent_ip, ftrace_get_regs(fregs), entry_data); > + ret = fp->entry_handler(fp, ip, parent_ip, fregs, entry_data); > > /* If entry_handler returns !0, nmissed is not counted. */ > if (rh) { > @@ -182,7 +182,7 @@ static void fprobe_init(struct fprobe *fp) > fp->ops.func = fprobe_kprobe_handler; > else > fp->ops.func = fprobe_handler; > - fp->ops.flags |= FTRACE_OPS_FL_SAVE_REGS; > + fp->ops.flags |= FTRACE_OPS_FL_SAVE_ARGS; so with this change you move to ftrace_caller trampoline, but we need ftrace_regs_caller right? otherwise the (!regs) check in kprobe_multi_link_handler will be allways true IIUC jirka > } > > static int fprobe_init_rethook(struct fprobe *fp, int num) > diff --git a/kernel/trace/trace_fprobe.c b/kernel/trace/trace_fprobe.c > index 7d2ddbcfa377..ef6b36fd05ae 100644 > --- a/kernel/trace/trace_fprobe.c > +++ b/kernel/trace/trace_fprobe.c > @@ -320,12 +320,16 @@ NOKPROBE_SYMBOL(fexit_perf_func); > #endif /* CONFIG_PERF_EVENTS */ > > static int fentry_dispatcher(struct fprobe *fp, unsigned long entry_ip, > - unsigned long ret_ip, struct pt_regs *regs, > + unsigned long ret_ip, struct ftrace_regs *fregs, > void *entry_data) > { > struct trace_fprobe *tf = container_of(fp, struct trace_fprobe, fp); > + struct pt_regs *regs = ftrace_get_regs(fregs); > int ret = 0; > > + if (!regs) > + return 0; > + > if (trace_probe_test_flag(&tf->tp, TP_FLAG_TRACE)) > fentry_trace_func(tf, entry_ip, regs); > #ifdef CONFIG_PERF_EVENTS > diff --git a/lib/test_fprobe.c b/lib/test_fprobe.c > index 24de0e5ff859..ff607babba18 100644 > --- a/lib/test_fprobe.c > +++ b/lib/test_fprobe.c > @@ -40,7 +40,7 @@ static noinline u32 fprobe_selftest_nest_target(u32 value, u32 (*nest)(u32)) > > static notrace int fp_entry_handler(struct fprobe *fp, unsigned long ip, > unsigned long ret_ip, > - struct pt_regs *regs, void *data) > + struct ftrace_regs *fregs, void *data) > { > KUNIT_EXPECT_FALSE(current_test, preemptible()); > /* This can be called on the fprobe_selftest_target and the fprobe_selftest_target2 */ > @@ -81,7 +81,7 @@ static notrace void fp_exit_handler(struct fprobe *fp, unsigned long ip, > > static notrace int nest_entry_handler(struct fprobe *fp, unsigned long ip, > unsigned long ret_ip, > - struct pt_regs *regs, void *data) > + struct ftrace_regs *fregs, void *data) > { > KUNIT_EXPECT_FALSE(current_test, preemptible()); > return 0; > diff --git a/samples/fprobe/fprobe_example.c b/samples/fprobe/fprobe_example.c > index 64e715e7ed11..1545a1aac616 100644 > --- a/samples/fprobe/fprobe_example.c > +++ b/samples/fprobe/fprobe_example.c > @@ -50,7 +50,7 @@ static void show_backtrace(void) > > static int sample_entry_handler(struct fprobe *fp, unsigned long ip, > unsigned long ret_ip, > - struct pt_regs *regs, void *data) > + struct ftrace_regs *fregs, void *data) > { > if (use_trace) > /* >
On Tue, 19 Dec 2023 14:23:48 +0100 Jiri Olsa <olsajiri@gmail.com> wrote: > On Mon, Dec 18, 2023 at 10:16:23PM +0900, Masami Hiramatsu (Google) wrote: > > SNIP > > > diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c > > index 84e8a0f6e4e0..d3f8745d8ead 100644 > > --- a/kernel/trace/bpf_trace.c > > +++ b/kernel/trace/bpf_trace.c > > @@ -2503,7 +2503,7 @@ static int __init bpf_event_init(void) > > fs_initcall(bpf_event_init); > > #endif /* CONFIG_MODULES */ > > > > -#ifdef CONFIG_FPROBE > > +#if defined(CONFIG_FPROBE) && defined(CONFIG_DYNAMIC_FTRACE_WITH_REGS) > > struct bpf_kprobe_multi_link { > > struct bpf_link link; > > struct fprobe fp; > > @@ -2733,10 +2733,14 @@ kprobe_multi_link_prog_run(struct bpf_kprobe_multi_link *link, > > > > static int > > kprobe_multi_link_handler(struct fprobe *fp, unsigned long fentry_ip, > > - unsigned long ret_ip, struct pt_regs *regs, > > + unsigned long ret_ip, struct ftrace_regs *fregs, > > void *data) > > { > > struct bpf_kprobe_multi_link *link; > > + struct pt_regs *regs = ftrace_get_regs(fregs); > > + > > + if (!regs) > > + return 0; > > > > link = container_of(fp, struct bpf_kprobe_multi_link, fp); > > kprobe_multi_link_prog_run(link, get_entry_ip(fentry_ip), regs); > > @@ -3008,7 +3012,7 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr > > kvfree(cookies); > > return err; > > } > > -#else /* !CONFIG_FPROBE */ > > +#else /* !CONFIG_FPROBE || !CONFIG_DYNAMIC_FTRACE_WITH_REGS */ > > int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog) > > { > > return -EOPNOTSUPP; > > diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c > > index 6cd2a4e3afb8..f12569494d8a 100644 > > --- a/kernel/trace/fprobe.c > > +++ b/kernel/trace/fprobe.c > > @@ -46,7 +46,7 @@ static inline void __fprobe_handler(unsigned long ip, unsigned long parent_ip, > > } > > > > if (fp->entry_handler) > > - ret = fp->entry_handler(fp, ip, parent_ip, ftrace_get_regs(fregs), entry_data); > > + ret = fp->entry_handler(fp, ip, parent_ip, fregs, entry_data); > > > > /* If entry_handler returns !0, nmissed is not counted. */ > > if (rh) { > > @@ -182,7 +182,7 @@ static void fprobe_init(struct fprobe *fp) > > fp->ops.func = fprobe_kprobe_handler; > > else > > fp->ops.func = fprobe_handler; > > - fp->ops.flags |= FTRACE_OPS_FL_SAVE_REGS; > > + fp->ops.flags |= FTRACE_OPS_FL_SAVE_ARGS; > > so with this change you move to ftrace_caller trampoline, > but we need ftrace_regs_caller right? Yes, that's right. > > otherwise the (!regs) check in kprobe_multi_link_handler > will be allways true IIUC Ah, OK. So until we move to fgraph [28/34], keep this flag SAVE_REGS then kprobe_multi test will pass. OK, let me keep it so. Thank you! > > jirka > > > } > > > > static int fprobe_init_rethook(struct fprobe *fp, int num) > > diff --git a/kernel/trace/trace_fprobe.c b/kernel/trace/trace_fprobe.c > > index 7d2ddbcfa377..ef6b36fd05ae 100644 > > --- a/kernel/trace/trace_fprobe.c > > +++ b/kernel/trace/trace_fprobe.c > > @@ -320,12 +320,16 @@ NOKPROBE_SYMBOL(fexit_perf_func); > > #endif /* CONFIG_PERF_EVENTS */ > > > > static int fentry_dispatcher(struct fprobe *fp, unsigned long entry_ip, > > - unsigned long ret_ip, struct pt_regs *regs, > > + unsigned long ret_ip, struct ftrace_regs *fregs, > > void *entry_data) > > { > > struct trace_fprobe *tf = container_of(fp, struct trace_fprobe, fp); > > + struct pt_regs *regs = ftrace_get_regs(fregs); > > int ret = 0; > > > > + if (!regs) > > + return 0; > > + > > if (trace_probe_test_flag(&tf->tp, TP_FLAG_TRACE)) > > fentry_trace_func(tf, entry_ip, regs); > > #ifdef CONFIG_PERF_EVENTS > > diff --git a/lib/test_fprobe.c b/lib/test_fprobe.c > > index 24de0e5ff859..ff607babba18 100644 > > --- a/lib/test_fprobe.c > > +++ b/lib/test_fprobe.c > > @@ -40,7 +40,7 @@ static noinline u32 fprobe_selftest_nest_target(u32 value, u32 (*nest)(u32)) > > > > static notrace int fp_entry_handler(struct fprobe *fp, unsigned long ip, > > unsigned long ret_ip, > > - struct pt_regs *regs, void *data) > > + struct ftrace_regs *fregs, void *data) > > { > > KUNIT_EXPECT_FALSE(current_test, preemptible()); > > /* This can be called on the fprobe_selftest_target and the fprobe_selftest_target2 */ > > @@ -81,7 +81,7 @@ static notrace void fp_exit_handler(struct fprobe *fp, unsigned long ip, > > > > static notrace int nest_entry_handler(struct fprobe *fp, unsigned long ip, > > unsigned long ret_ip, > > - struct pt_regs *regs, void *data) > > + struct ftrace_regs *fregs, void *data) > > { > > KUNIT_EXPECT_FALSE(current_test, preemptible()); > > return 0; > > diff --git a/samples/fprobe/fprobe_example.c b/samples/fprobe/fprobe_example.c > > index 64e715e7ed11..1545a1aac616 100644 > > --- a/samples/fprobe/fprobe_example.c > > +++ b/samples/fprobe/fprobe_example.c > > @@ -50,7 +50,7 @@ static void show_backtrace(void) > > > > static int sample_entry_handler(struct fprobe *fp, unsigned long ip, > > unsigned long ret_ip, > > - struct pt_regs *regs, void *data) > > + struct ftrace_regs *fregs, void *data) > > { > > if (use_trace) > > /* > >
diff --git a/include/linux/fprobe.h b/include/linux/fprobe.h index 3e03758151f4..36c0595f7b93 100644 --- a/include/linux/fprobe.h +++ b/include/linux/fprobe.h @@ -35,7 +35,7 @@ struct fprobe { int nr_maxactive; int (*entry_handler)(struct fprobe *fp, unsigned long entry_ip, - unsigned long ret_ip, struct pt_regs *regs, + unsigned long ret_ip, struct ftrace_regs *regs, void *entry_data); void (*exit_handler)(struct fprobe *fp, unsigned long entry_ip, unsigned long ret_ip, struct pt_regs *regs, diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 308b3bec01b1..805d72ab77c6 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -290,7 +290,7 @@ config DYNAMIC_FTRACE_WITH_ARGS config FPROBE bool "Kernel Function Probe (fprobe)" depends on FUNCTION_TRACER - depends on DYNAMIC_FTRACE_WITH_REGS + depends on DYNAMIC_FTRACE_WITH_REGS || DYNAMIC_FTRACE_WITH_ARGS depends on HAVE_RETHOOK select RETHOOK default n @@ -675,6 +675,7 @@ config FPROBE_EVENTS select TRACING select PROBE_EVENTS select DYNAMIC_EVENTS + depends on DYNAMIC_FTRACE_WITH_REGS default y help This allows user to add tracing events on the function entry and diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 84e8a0f6e4e0..d3f8745d8ead 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -2503,7 +2503,7 @@ static int __init bpf_event_init(void) fs_initcall(bpf_event_init); #endif /* CONFIG_MODULES */ -#ifdef CONFIG_FPROBE +#if defined(CONFIG_FPROBE) && defined(CONFIG_DYNAMIC_FTRACE_WITH_REGS) struct bpf_kprobe_multi_link { struct bpf_link link; struct fprobe fp; @@ -2733,10 +2733,14 @@ kprobe_multi_link_prog_run(struct bpf_kprobe_multi_link *link, static int kprobe_multi_link_handler(struct fprobe *fp, unsigned long fentry_ip, - unsigned long ret_ip, struct pt_regs *regs, + unsigned long ret_ip, struct ftrace_regs *fregs, void *data) { struct bpf_kprobe_multi_link *link; + struct pt_regs *regs = ftrace_get_regs(fregs); + + if (!regs) + return 0; link = container_of(fp, struct bpf_kprobe_multi_link, fp); kprobe_multi_link_prog_run(link, get_entry_ip(fentry_ip), regs); @@ -3008,7 +3012,7 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr kvfree(cookies); return err; } -#else /* !CONFIG_FPROBE */ +#else /* !CONFIG_FPROBE || !CONFIG_DYNAMIC_FTRACE_WITH_REGS */ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog) { return -EOPNOTSUPP; diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c index 6cd2a4e3afb8..f12569494d8a 100644 --- a/kernel/trace/fprobe.c +++ b/kernel/trace/fprobe.c @@ -46,7 +46,7 @@ static inline void __fprobe_handler(unsigned long ip, unsigned long parent_ip, } if (fp->entry_handler) - ret = fp->entry_handler(fp, ip, parent_ip, ftrace_get_regs(fregs), entry_data); + ret = fp->entry_handler(fp, ip, parent_ip, fregs, entry_data); /* If entry_handler returns !0, nmissed is not counted. */ if (rh) { @@ -182,7 +182,7 @@ static void fprobe_init(struct fprobe *fp) fp->ops.func = fprobe_kprobe_handler; else fp->ops.func = fprobe_handler; - fp->ops.flags |= FTRACE_OPS_FL_SAVE_REGS; + fp->ops.flags |= FTRACE_OPS_FL_SAVE_ARGS; } static int fprobe_init_rethook(struct fprobe *fp, int num) diff --git a/kernel/trace/trace_fprobe.c b/kernel/trace/trace_fprobe.c index 7d2ddbcfa377..ef6b36fd05ae 100644 --- a/kernel/trace/trace_fprobe.c +++ b/kernel/trace/trace_fprobe.c @@ -320,12 +320,16 @@ NOKPROBE_SYMBOL(fexit_perf_func); #endif /* CONFIG_PERF_EVENTS */ static int fentry_dispatcher(struct fprobe *fp, unsigned long entry_ip, - unsigned long ret_ip, struct pt_regs *regs, + unsigned long ret_ip, struct ftrace_regs *fregs, void *entry_data) { struct trace_fprobe *tf = container_of(fp, struct trace_fprobe, fp); + struct pt_regs *regs = ftrace_get_regs(fregs); int ret = 0; + if (!regs) + return 0; + if (trace_probe_test_flag(&tf->tp, TP_FLAG_TRACE)) fentry_trace_func(tf, entry_ip, regs); #ifdef CONFIG_PERF_EVENTS diff --git a/lib/test_fprobe.c b/lib/test_fprobe.c index 24de0e5ff859..ff607babba18 100644 --- a/lib/test_fprobe.c +++ b/lib/test_fprobe.c @@ -40,7 +40,7 @@ static noinline u32 fprobe_selftest_nest_target(u32 value, u32 (*nest)(u32)) static notrace int fp_entry_handler(struct fprobe *fp, unsigned long ip, unsigned long ret_ip, - struct pt_regs *regs, void *data) + struct ftrace_regs *fregs, void *data) { KUNIT_EXPECT_FALSE(current_test, preemptible()); /* This can be called on the fprobe_selftest_target and the fprobe_selftest_target2 */ @@ -81,7 +81,7 @@ static notrace void fp_exit_handler(struct fprobe *fp, unsigned long ip, static notrace int nest_entry_handler(struct fprobe *fp, unsigned long ip, unsigned long ret_ip, - struct pt_regs *regs, void *data) + struct ftrace_regs *fregs, void *data) { KUNIT_EXPECT_FALSE(current_test, preemptible()); return 0; diff --git a/samples/fprobe/fprobe_example.c b/samples/fprobe/fprobe_example.c index 64e715e7ed11..1545a1aac616 100644 --- a/samples/fprobe/fprobe_example.c +++ b/samples/fprobe/fprobe_example.c @@ -50,7 +50,7 @@ static void show_backtrace(void) static int sample_entry_handler(struct fprobe *fp, unsigned long ip, unsigned long ret_ip, - struct pt_regs *regs, void *data) + struct ftrace_regs *fregs, void *data) { if (use_trace) /*