mirror of https://github.com/torvalds/linux.git
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>
This commit is contained in:
parent
2ca8c112c9
commit
46bc082388
|
|
@ -10,7 +10,7 @@
|
|||
struct fprobe;
|
||||
|
||||
typedef int (*fprobe_entry_cb)(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);
|
||||
|
||||
typedef void (*fprobe_exit_cb)(struct fprobe *fp, unsigned long entry_ip,
|
||||
|
|
|
|||
|
|
@ -297,7 +297,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
|
||||
|
|
@ -682,6 +682,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
|
||||
|
|
|
|||
|
|
@ -2561,7 +2561,7 @@ struct bpf_session_run_ctx {
|
|||
void *data;
|
||||
};
|
||||
|
||||
#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;
|
||||
|
|
@ -2813,12 +2813,16 @@ 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 pt_regs *regs = ftrace_get_regs(fregs);
|
||||
struct bpf_kprobe_multi_link *link;
|
||||
int err;
|
||||
|
||||
if (!regs)
|
||||
return 0;
|
||||
|
||||
link = container_of(fp, struct bpf_kprobe_multi_link, fp);
|
||||
err = kprobe_multi_link_prog_run(link, get_entry_ip(fentry_ip), regs, false, data);
|
||||
return is_kprobe_session(link->link.prog) ? err : 0;
|
||||
|
|
@ -3093,7 +3097,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;
|
||||
|
|
|
|||
|
|
@ -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,6 +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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -217,12 +217,13 @@ NOKPROBE_SYMBOL(fentry_trace_func);
|
|||
|
||||
/* function exit handler */
|
||||
static int trace_fprobe_entry_handler(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);
|
||||
|
||||
if (tf->tp.entry_arg)
|
||||
if (regs && tf->tp.entry_arg)
|
||||
store_trace_entry_data(entry_data, &tf->tp, regs);
|
||||
|
||||
return 0;
|
||||
|
|
@ -339,12 +340,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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue