Commit 46bc0823 authored by Masami Hiramatsu (Google)'s avatar Masami Hiramatsu (Google) Committed by Steven Rostedt (Google)
Browse files

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: default avatarMasami Hiramatsu (Google) <mhiramat@kernel.org>
Acked-by: default avatarFlorent Revest <revest@chromium.org>
Signed-off-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
parent 2ca8c112
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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,
+2 −1
Original line number Diff line number Diff line
@@ -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
+7 −3
Original line number Diff line number Diff line
@@ -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;
+2 −1
Original line number Diff line number Diff line
@@ -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;
}

+8 −3
Original line number Diff line number Diff line
@@ -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
Loading