Commit cb16330d authored by Masami Hiramatsu (Google)'s avatar Masami Hiramatsu (Google)
Browse files

fprobe: Pass return address to the handlers

Pass return address as 'ret_ip' to the fprobe entry and return handlers
so that the fprobe user handler can get the reutrn address without
analyzing arch-dependent pt_regs.

Link: https://lore.kernel.org/all/168507467664.913472.11642316698862778600.stgit@mhiramat.roam.corp.google.com/



Signed-off-by: default avatarMasami Hiramatsu (Google) <mhiramat@kernel.org>
parent 9561de3a
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -35,9 +35,11 @@ struct fprobe {
	int			nr_maxactive;

	int (*entry_handler)(struct fprobe *fp, unsigned long entry_ip,
			     struct pt_regs *regs, void *entry_data);
			     unsigned long ret_ip, struct pt_regs *regs,
			     void *entry_data);
	void (*exit_handler)(struct fprobe *fp, unsigned long entry_ip,
			     struct pt_regs *regs, void *entry_data);
			     unsigned long ret_ip, struct pt_regs *regs,
			     void *entry_data);
};

/* This fprobe is soft-disabled. */
+1 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@

struct rethook_node;

typedef void (*rethook_handler_t) (struct rethook_node *, void *, struct pt_regs *);
typedef void (*rethook_handler_t) (struct rethook_node *, void *, unsigned long, struct pt_regs *);

/**
 * struct rethook - The rethook management data structure.
+1 −0
Original line number Diff line number Diff line
@@ -2127,6 +2127,7 @@ static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs)
NOKPROBE_SYMBOL(pre_handler_kretprobe);

static void kretprobe_rethook_handler(struct rethook_node *rh, void *data,
				      unsigned long ret_addr,
				      struct pt_regs *regs)
{
	struct kretprobe *rp = (struct kretprobe *)data;
+4 −2
Original line number Diff line number Diff line
@@ -2642,7 +2642,8 @@ kprobe_multi_link_prog_run(struct bpf_kprobe_multi_link *link,

static int
kprobe_multi_link_handler(struct fprobe *fp, unsigned long fentry_ip,
			  struct pt_regs *regs, void *data)
			  unsigned long ret_ip, struct pt_regs *regs,
			  void *data)
{
	struct bpf_kprobe_multi_link *link;

@@ -2653,7 +2654,8 @@ kprobe_multi_link_handler(struct fprobe *fp, unsigned long fentry_ip,

static void
kprobe_multi_link_exit_handler(struct fprobe *fp, unsigned long fentry_ip,
			       struct pt_regs *regs, void *data)
			       unsigned long ret_ip, struct pt_regs *regs,
			       void *data)
{
	struct bpf_kprobe_multi_link *link;

+3 −3
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, ftrace_get_regs(fregs), entry_data);
		ret = fp->entry_handler(fp, ip, parent_ip, ftrace_get_regs(fregs), entry_data);

	/* If entry_handler returns !0, nmissed is not counted. */
	if (rh) {
@@ -112,7 +112,7 @@ static void fprobe_kprobe_handler(unsigned long ip, unsigned long parent_ip,
}

static void fprobe_exit_handler(struct rethook_node *rh, void *data,
				struct pt_regs *regs)
				unsigned long ret_ip, struct pt_regs *regs)
{
	struct fprobe *fp = (struct fprobe *)data;
	struct fprobe_rethook_node *fpr;
@@ -133,7 +133,7 @@ static void fprobe_exit_handler(struct rethook_node *rh, void *data,
		return;
	}

	fp->exit_handler(fp, fpr->entry_ip, regs,
	fp->exit_handler(fp, fpr->entry_ip, ret_ip, regs,
			 fp->entry_data_size ? (void *)fpr->data : NULL);
	ftrace_test_recursion_unlock(bit);
}
Loading