From: Jiri Olsa <jolsa@redhat.com>
To: Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>,
Masami Hiramatsu <mhiramat@kernel.org>
Cc: netdev@vger.kernel.org, bpf@vger.kernel.org,
lkml <linux-kernel@vger.kernel.org>,
Martin KaFai Lau <kafai@fb.com>, Song Liu <songliubraving@fb.com>,
Yonghong Song <yhs@fb.com>,
John Fastabend <john.fastabend@gmail.com>,
KP Singh <kpsingh@chromium.org>,
Steven Rostedt <rostedt@goodmis.org>,
Jiri Olsa <olsajiri@gmail.com>
Subject: [PATCH 3/8] bpf: Add bpf_cookie support to fprobe
Date: Wed, 2 Feb 2022 14:53:28 +0100 [thread overview]
Message-ID: <20220202135333.190761-4-jolsa@kernel.org> (raw)
In-Reply-To: <20220202135333.190761-1-jolsa@kernel.org>
Adding support to call bpf_get_attach_cookie helper from
kprobe program attached by fprobe link.
The bpf_cookie is provided by array of u64 values, where
each value is paired with provided function address with
the same array index.
Suggested-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
include/linux/bpf.h | 2 +
include/uapi/linux/bpf.h | 1 +
kernel/bpf/syscall.c | 83 +++++++++++++++++++++++++++++++++-
kernel/trace/bpf_trace.c | 16 ++++++-
tools/include/uapi/linux/bpf.h | 1 +
5 files changed, 100 insertions(+), 3 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 6eb0b180d33b..7b65f05c0487 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1301,6 +1301,8 @@ static inline void bpf_reset_run_ctx(struct bpf_run_ctx *old_ctx)
#endif
}
+u64 bpf_fprobe_cookie(struct bpf_run_ctx *ctx, u64 ip);
+
/* BPF program asks to bypass CAP_NET_BIND_SERVICE in bind. */
#define BPF_RET_BIND_NO_CAP_NET_BIND_SERVICE (1 << 0)
/* BPF program asks to set CN on the packet. */
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index c0912f0a3dfe..0dc6aa4f9683 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -1484,6 +1484,7 @@ union bpf_attr {
__aligned_u64 addrs;
__u32 cnt;
__u32 flags;
+ __aligned_u64 bpf_cookies;
} fprobe;
};
} link_create;
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 0cfbb112c8e1..6c5e74bc43b6 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -33,6 +33,8 @@
#include <linux/rcupdate_trace.h>
#include <linux/memcontrol.h>
#include <linux/fprobe.h>
+#include <linux/bsearch.h>
+#include <linux/sort.h>
#define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \
(map)->map_type == BPF_MAP_TYPE_CGROUP_ARRAY || \
@@ -3025,10 +3027,18 @@ static int bpf_perf_link_attach(const union bpf_attr *attr, struct bpf_prog *pro
#ifdef CONFIG_FPROBE
+struct bpf_fprobe_cookie {
+ unsigned long addr;
+ u64 bpf_cookie;
+};
+
struct bpf_fprobe_link {
struct bpf_link link;
struct fprobe fp;
unsigned long *addrs;
+ struct bpf_run_ctx run_ctx;
+ struct bpf_fprobe_cookie *bpf_cookies;
+ u32 cnt;
};
static void bpf_fprobe_link_release(struct bpf_link *link)
@@ -3045,6 +3055,7 @@ static void bpf_fprobe_link_dealloc(struct bpf_link *link)
fprobe_link = container_of(link, struct bpf_fprobe_link, link);
kfree(fprobe_link->addrs);
+ kfree(fprobe_link->bpf_cookies);
kfree(fprobe_link);
}
@@ -3053,9 +3064,37 @@ static const struct bpf_link_ops bpf_fprobe_link_lops = {
.dealloc = bpf_fprobe_link_dealloc,
};
+static int bpf_fprobe_cookie_cmp(const void *_a, const void *_b)
+{
+ const struct bpf_fprobe_cookie *a = _a;
+ const struct bpf_fprobe_cookie *b = _b;
+
+ if (a->addr == b->addr)
+ return 0;
+ return a->addr < b->addr ? -1 : 1;
+}
+
+u64 bpf_fprobe_cookie(struct bpf_run_ctx *ctx, u64 ip)
+{
+ struct bpf_fprobe_link *fprobe_link;
+ struct bpf_fprobe_cookie *val, key = {
+ .addr = (unsigned long) ip,
+ };
+
+ if (!ctx)
+ return 0;
+ fprobe_link = container_of(ctx, struct bpf_fprobe_link, run_ctx);
+ if (!fprobe_link->bpf_cookies)
+ return 0;
+ val = bsearch(&key, fprobe_link->bpf_cookies, fprobe_link->cnt,
+ sizeof(key), bpf_fprobe_cookie_cmp);
+ return val ? val->bpf_cookie : 0;
+}
+
static int fprobe_link_prog_run(struct bpf_fprobe_link *fprobe_link,
struct pt_regs *regs)
{
+ struct bpf_run_ctx *old_run_ctx;
int err;
if (unlikely(__this_cpu_inc_return(bpf_prog_active) != 1)) {
@@ -3063,12 +3102,16 @@ static int fprobe_link_prog_run(struct bpf_fprobe_link *fprobe_link,
goto out;
}
+ old_run_ctx = bpf_set_run_ctx(&fprobe_link->run_ctx);
+
rcu_read_lock();
migrate_disable();
err = bpf_prog_run(fprobe_link->link.prog, regs);
migrate_enable();
rcu_read_unlock();
+ bpf_reset_run_ctx(old_run_ctx);
+
out:
__this_cpu_dec(bpf_prog_active);
return err;
@@ -3161,10 +3204,12 @@ static int fprobe_resolve_syms(const void *usyms, u32 cnt,
static int bpf_fprobe_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
{
+ struct bpf_fprobe_cookie *bpf_cookies = NULL;
struct bpf_fprobe_link *link = NULL;
struct bpf_link_primer link_primer;
+ void __user *ubpf_cookies;
+ u32 flags, cnt, i, size;
unsigned long *addrs;
- u32 flags, cnt, size;
void __user *uaddrs;
void __user *usyms;
int err;
@@ -3205,6 +3250,37 @@ static int bpf_fprobe_link_attach(const union bpf_attr *attr, struct bpf_prog *p
goto error;
}
+ ubpf_cookies = u64_to_user_ptr(attr->link_create.fprobe.bpf_cookies);
+ if (ubpf_cookies) {
+ u64 *tmp;
+
+ err = -ENOMEM;
+ tmp = kzalloc(size, GFP_KERNEL);
+ if (!tmp)
+ goto error;
+
+ if (copy_from_user(tmp, ubpf_cookies, size)) {
+ kfree(tmp);
+ err = -EFAULT;
+ goto error;
+ }
+
+ size = cnt * sizeof(*bpf_cookies);
+ bpf_cookies = kzalloc(size, GFP_KERNEL);
+ if (!bpf_cookies) {
+ kfree(tmp);
+ goto error;
+ }
+
+ for (i = 0; i < cnt; i++) {
+ bpf_cookies[i].addr = addrs[i];
+ bpf_cookies[i].bpf_cookie = tmp[i];
+ }
+
+ sort(bpf_cookies, cnt, sizeof(*bpf_cookies), bpf_fprobe_cookie_cmp, NULL);
+ kfree(tmp);
+ }
+
link = kzalloc(sizeof(*link), GFP_KERNEL);
if (!link) {
err = -ENOMEM;
@@ -3224,6 +3300,8 @@ static int bpf_fprobe_link_attach(const union bpf_attr *attr, struct bpf_prog *p
link->fp.entry_handler = fprobe_link_entry_handler;
link->addrs = addrs;
+ link->bpf_cookies = bpf_cookies;
+ link->cnt = cnt;
err = register_fprobe_ips(&link->fp, addrs, cnt);
if (err) {
@@ -3236,6 +3314,7 @@ static int bpf_fprobe_link_attach(const union bpf_attr *attr, struct bpf_prog *p
error:
kfree(link);
kfree(addrs);
+ kfree(bpf_cookies);
return err;
}
#else /* !CONFIG_FPROBE */
@@ -4476,7 +4555,7 @@ static int tracing_bpf_link_attach(const union bpf_attr *attr, bpfptr_t uattr,
return -EINVAL;
}
-#define BPF_LINK_CREATE_LAST_FIELD link_create.fprobe.flags
+#define BPF_LINK_CREATE_LAST_FIELD link_create.fprobe.bpf_cookies
static int link_create(union bpf_attr *attr, bpfptr_t uattr)
{
enum bpf_prog_type ptype;
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 28e59e31e3db..b54b2ef93928 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -1049,6 +1049,18 @@ static const struct bpf_func_proto bpf_get_func_ip_proto_fprobe = {
.arg1_type = ARG_PTR_TO_CTX,
};
+BPF_CALL_1(bpf_get_attach_cookie_fprobe, struct pt_regs *, regs)
+{
+ return bpf_fprobe_cookie(current->bpf_ctx, regs->ip);
+}
+
+static const struct bpf_func_proto bpf_get_attach_cookie_proto_fprobe = {
+ .func = bpf_get_attach_cookie_fprobe,
+ .gpl_only = false,
+ .ret_type = RET_INTEGER,
+ .arg1_type = ARG_PTR_TO_CTX,
+};
+
BPF_CALL_1(bpf_get_attach_cookie_trace, void *, ctx)
{
struct bpf_trace_run_ctx *run_ctx;
@@ -1295,7 +1307,9 @@ kprobe_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
return prog->expected_attach_type == BPF_TRACE_FPROBE ?
&bpf_get_func_ip_proto_fprobe : &bpf_get_func_ip_proto_kprobe;
case BPF_FUNC_get_attach_cookie:
- return &bpf_get_attach_cookie_proto_trace;
+ return prog->expected_attach_type == BPF_TRACE_FPROBE ?
+ &bpf_get_attach_cookie_proto_fprobe :
+ &bpf_get_attach_cookie_proto_trace;
default:
return bpf_tracing_func_proto(func_id, prog);
}
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index c0912f0a3dfe..0dc6aa4f9683 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -1484,6 +1484,7 @@ union bpf_attr {
__aligned_u64 addrs;
__u32 cnt;
__u32 flags;
+ __aligned_u64 bpf_cookies;
} fprobe;
};
} link_create;
--
2.34.1
next prev parent reply other threads:[~2022-02-02 13:54 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-02 13:53 [PATCH 0/8] bpf: Add fprobe link Jiri Olsa
2022-02-02 13:53 ` [PATCH 1/8] bpf: Add support to attach kprobe program with fprobe Jiri Olsa
2022-02-07 18:59 ` Andrii Nakryiko
2022-02-08 8:56 ` Jiri Olsa
2022-02-02 13:53 ` [PATCH 2/8] bpf: Add bpf_get_func_ip kprobe helper for fprobe link Jiri Olsa
2022-02-07 18:59 ` Andrii Nakryiko
2022-02-07 21:01 ` Alexei Starovoitov
2022-02-09 15:01 ` Jiri Olsa
2022-02-09 16:05 ` Andrii Nakryiko
2022-02-09 19:14 ` Jiri Olsa
2022-02-02 13:53 ` Jiri Olsa [this message]
2022-02-07 18:59 ` [PATCH 3/8] bpf: Add bpf_cookie support to fprobe Andrii Nakryiko
2022-02-08 9:07 ` Jiri Olsa
2022-02-08 23:35 ` Andrii Nakryiko
2022-02-08 23:46 ` Jiri Olsa
2022-02-08 23:53 ` Andrii Nakryiko
2022-02-02 13:53 ` [PATCH 4/8] libbpf: Add libbpf__kallsyms_parse function Jiri Olsa
2022-02-07 18:59 ` Andrii Nakryiko
2022-02-08 9:08 ` Jiri Olsa
2022-02-02 13:53 ` [PATCH 5/8] libbpf: Add bpf_link_create support for multi kprobes Jiri Olsa
2022-02-02 13:53 ` [PATCH 6/8] libbpf: Add bpf_program__attach_kprobe_opts " Jiri Olsa
2022-02-07 18:59 ` Andrii Nakryiko
2022-02-08 9:12 ` Jiri Olsa
2022-02-02 13:53 ` [PATCH 7/8] selftest/bpf: Add fprobe attach test Jiri Olsa
2022-02-02 13:53 ` [PATCH 8/8] selftest/bpf: Add fprobe test for bpf_cookie values Jiri Olsa
2022-02-07 18:59 ` Andrii Nakryiko
2022-02-08 9:15 ` Jiri Olsa
2022-02-08 23:24 ` Andrii Nakryiko
2022-02-02 17:09 ` [PATCH 0/8] bpf: Add fprobe link Alexei Starovoitov
2022-02-02 17:24 ` Jiri Olsa
2022-02-02 17:30 ` Alexei Starovoitov
2022-02-03 15:06 ` Jiri Olsa
2022-02-04 0:46 ` Masami Hiramatsu
2022-02-04 1:34 ` Alexei Starovoitov
2022-02-04 2:07 ` Masami Hiramatsu
2022-02-04 2:12 ` Alexei Starovoitov
2022-02-04 2:19 ` Steven Rostedt
2022-02-04 2:42 ` Alexei Starovoitov
2022-02-04 3:17 ` Masami Hiramatsu
2022-02-04 3:59 ` Masami Hiramatsu
2022-02-15 13:21 ` Jiri Olsa
2022-02-16 18:27 ` Andrii Nakryiko
2022-02-17 14:03 ` Masami Hiramatsu
2022-02-17 22:01 ` Andrii Nakryiko
2022-02-18 4:07 ` Masami Hiramatsu
2022-02-18 19:46 ` Andrii Nakryiko
2022-02-19 2:10 ` Alexei Starovoitov
2022-02-21 7:18 ` Masami Hiramatsu
2022-02-22 12:42 ` Jiri Olsa
2022-02-04 3:14 ` Masami Hiramatsu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220202135333.190761-4-jolsa@kernel.org \
--to=jolsa@redhat.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=john.fastabend@gmail.com \
--cc=kafai@fb.com \
--cc=kpsingh@chromium.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mhiramat@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=olsajiri@gmail.com \
--cc=rostedt@goodmis.org \
--cc=songliubraving@fb.com \
--cc=yhs@fb.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.