* [PATCH bpf-next 1/2] libbpf: support modules in bpf_program__set_attach_target() API
2020-12-11 21:58 [PATCH bpf-next 0/2] libbpf: support modules in set_attach_target() API Andrii Nakryiko
@ 2020-12-11 21:58 ` Andrii Nakryiko
2020-12-11 21:58 ` [PATCH bpf-next 2/2] selftests/bpf: add set_attach_target() API selftest for module target Andrii Nakryiko
2020-12-14 15:50 ` [PATCH bpf-next 0/2] libbpf: support modules in set_attach_target() API patchwork-bot+netdevbpf
2 siblings, 0 replies; 4+ messages in thread
From: Andrii Nakryiko @ 2020-12-11 21:58 UTC (permalink / raw)
To: bpf, netdev, ast, daniel; +Cc: andrii, kernel-team
Support finding kernel targets in kernel modules when using
bpf_program__set_attach_target() API. This brings it up to par with what
libbpf supports when doing declarative SEC()-based target determination.
Some minor internal refactoring was needed to make sure vmlinux BTF can be
loaded before bpf_object's load phase.
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
---
tools/lib/bpf/libbpf.c | 64 ++++++++++++++++++++++++++----------------
1 file changed, 40 insertions(+), 24 deletions(-)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 9be88a90a4aa..6ae748f6ea11 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -2518,7 +2518,7 @@ static int bpf_object__finalize_btf(struct bpf_object *obj)
return 0;
}
-static inline bool libbpf_prog_needs_vmlinux_btf(struct bpf_program *prog)
+static bool prog_needs_vmlinux_btf(struct bpf_program *prog)
{
if (prog->type == BPF_PROG_TYPE_STRUCT_OPS ||
prog->type == BPF_PROG_TYPE_LSM)
@@ -2533,37 +2533,43 @@ static inline bool libbpf_prog_needs_vmlinux_btf(struct bpf_program *prog)
return false;
}
-static int bpf_object__load_vmlinux_btf(struct bpf_object *obj)
+static bool obj_needs_vmlinux_btf(const struct bpf_object *obj)
{
- bool need_vmlinux_btf = false;
struct bpf_program *prog;
- int i, err;
+ int i;
/* CO-RE relocations need kernel BTF */
if (obj->btf_ext && obj->btf_ext->core_relo_info.len)
- need_vmlinux_btf = true;
+ return true;
/* Support for typed ksyms needs kernel BTF */
for (i = 0; i < obj->nr_extern; i++) {
const struct extern_desc *ext;
ext = &obj->externs[i];
- if (ext->type == EXT_KSYM && ext->ksym.type_id) {
- need_vmlinux_btf = true;
- break;
- }
+ if (ext->type == EXT_KSYM && ext->ksym.type_id)
+ return true;
}
bpf_object__for_each_program(prog, obj) {
if (!prog->load)
continue;
- if (libbpf_prog_needs_vmlinux_btf(prog)) {
- need_vmlinux_btf = true;
- break;
- }
+ if (prog_needs_vmlinux_btf(prog))
+ return true;
}
- if (!need_vmlinux_btf)
+ return false;
+}
+
+static int bpf_object__load_vmlinux_btf(struct bpf_object *obj, bool force)
+{
+ int err;
+
+ /* btf_vmlinux could be loaded earlier */
+ if (obj->btf_vmlinux)
+ return 0;
+
+ if (!force && !obj_needs_vmlinux_btf(obj))
return 0;
obj->btf_vmlinux = libbpf_find_kernel_btf();
@@ -7475,7 +7481,7 @@ int bpf_object__load_xattr(struct bpf_object_load_attr *attr)
}
err = bpf_object__probe_loading(obj);
- err = err ? : bpf_object__load_vmlinux_btf(obj);
+ err = err ? : bpf_object__load_vmlinux_btf(obj, false);
err = err ? : bpf_object__resolve_externs(obj, obj->kconfig);
err = err ? : bpf_object__sanitize_and_load_btf(obj);
err = err ? : bpf_object__sanitize_maps(obj);
@@ -10870,23 +10876,33 @@ int bpf_program__set_attach_target(struct bpf_program *prog,
int attach_prog_fd,
const char *attach_func_name)
{
- int btf_id;
+ int btf_obj_fd = 0, btf_id = 0, err;
if (!prog || attach_prog_fd < 0 || !attach_func_name)
return -EINVAL;
- if (attach_prog_fd)
+ if (prog->obj->loaded)
+ return -EINVAL;
+
+ if (attach_prog_fd) {
btf_id = libbpf_find_prog_btf_id(attach_func_name,
attach_prog_fd);
- else
- btf_id = libbpf_find_vmlinux_btf_id(attach_func_name,
- prog->expected_attach_type);
-
- if (btf_id < 0)
- return btf_id;
+ if (btf_id < 0)
+ return btf_id;
+ } else {
+ /* load btf_vmlinux, if not yet */
+ err = bpf_object__load_vmlinux_btf(prog->obj, true);
+ if (err)
+ return err;
+ err = find_kernel_btf_id(prog->obj, attach_func_name,
+ prog->expected_attach_type,
+ &btf_obj_fd, &btf_id);
+ if (err)
+ return err;
+ }
prog->attach_btf_id = btf_id;
- prog->attach_btf_obj_fd = 0;
+ prog->attach_btf_obj_fd = btf_obj_fd;
prog->attach_prog_fd = attach_prog_fd;
return 0;
}
--
2.24.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH bpf-next 2/2] selftests/bpf: add set_attach_target() API selftest for module target
2020-12-11 21:58 [PATCH bpf-next 0/2] libbpf: support modules in set_attach_target() API Andrii Nakryiko
2020-12-11 21:58 ` [PATCH bpf-next 1/2] libbpf: support modules in bpf_program__set_attach_target() API Andrii Nakryiko
@ 2020-12-11 21:58 ` Andrii Nakryiko
2020-12-14 15:50 ` [PATCH bpf-next 0/2] libbpf: support modules in set_attach_target() API patchwork-bot+netdevbpf
2 siblings, 0 replies; 4+ messages in thread
From: Andrii Nakryiko @ 2020-12-11 21:58 UTC (permalink / raw)
To: bpf, netdev, ast, daniel; +Cc: andrii, kernel-team
Add test for bpf_program__set_attach_target() API, validating it can find
kernel module fentry target.
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
---
.../testing/selftests/bpf/prog_tests/module_attach.c | 11 ++++++++++-
.../testing/selftests/bpf/progs/test_module_attach.c | 11 +++++++++++
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/module_attach.c b/tools/testing/selftests/bpf/prog_tests/module_attach.c
index 4b65e9918764..50796b651f72 100644
--- a/tools/testing/selftests/bpf/prog_tests/module_attach.c
+++ b/tools/testing/selftests/bpf/prog_tests/module_attach.c
@@ -28,10 +28,18 @@ void test_module_attach(void)
struct test_module_attach__bss *bss;
int err;
- skel = test_module_attach__open_and_load();
+ skel = test_module_attach__open();
if (CHECK(!skel, "skel_open", "failed to open skeleton\n"))
return;
+ err = bpf_program__set_attach_target(skel->progs.handle_fentry_manual,
+ 0, "bpf_testmod_test_read");
+ ASSERT_OK(err, "set_attach_target");
+
+ err = test_module_attach__load(skel);
+ if (CHECK(err, "skel_load", "failed to load skeleton\n"))
+ return;
+
bss = skel->bss;
err = test_module_attach__attach(skel);
@@ -44,6 +52,7 @@ void test_module_attach(void)
ASSERT_EQ(bss->raw_tp_read_sz, READ_SZ, "raw_tp");
ASSERT_EQ(bss->tp_btf_read_sz, READ_SZ, "tp_btf");
ASSERT_EQ(bss->fentry_read_sz, READ_SZ, "fentry");
+ ASSERT_EQ(bss->fentry_manual_read_sz, READ_SZ, "fentry_manual");
ASSERT_EQ(bss->fexit_read_sz, READ_SZ, "fexit");
ASSERT_EQ(bss->fexit_ret, -EIO, "fexit_tet");
ASSERT_EQ(bss->fmod_ret_read_sz, READ_SZ, "fmod_ret");
diff --git a/tools/testing/selftests/bpf/progs/test_module_attach.c b/tools/testing/selftests/bpf/progs/test_module_attach.c
index b563563df172..efd1e287ac17 100644
--- a/tools/testing/selftests/bpf/progs/test_module_attach.c
+++ b/tools/testing/selftests/bpf/progs/test_module_attach.c
@@ -38,6 +38,17 @@ int BPF_PROG(handle_fentry,
return 0;
}
+__u32 fentry_manual_read_sz = 0;
+
+SEC("fentry/placeholder")
+int BPF_PROG(handle_fentry_manual,
+ struct file *file, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf, loff_t off, size_t len)
+{
+ fentry_manual_read_sz = len;
+ return 0;
+}
+
__u32 fexit_read_sz = 0;
int fexit_ret = 0;
--
2.24.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH bpf-next 0/2] libbpf: support modules in set_attach_target() API
2020-12-11 21:58 [PATCH bpf-next 0/2] libbpf: support modules in set_attach_target() API Andrii Nakryiko
2020-12-11 21:58 ` [PATCH bpf-next 1/2] libbpf: support modules in bpf_program__set_attach_target() API Andrii Nakryiko
2020-12-11 21:58 ` [PATCH bpf-next 2/2] selftests/bpf: add set_attach_target() API selftest for module target Andrii Nakryiko
@ 2020-12-14 15:50 ` patchwork-bot+netdevbpf
2 siblings, 0 replies; 4+ messages in thread
From: patchwork-bot+netdevbpf @ 2020-12-14 15:50 UTC (permalink / raw)
To: Andrii Nakryiko; +Cc: bpf, netdev, ast, daniel, kernel-team
Hello:
This series was applied to bpf/bpf-next.git (refs/heads/master):
On Fri, 11 Dec 2020 13:58:23 -0800 you wrote:
> Add support for finding BTF-based kernel attach targets (fentry/fexit
> functions, tp_btf tracepoints, etc) with programmatic
> bpf_program__set_attach_target() API. It is now as capable as libbpf's
> SEC()-based logic.
>
> Andrii Nakryiko (2):
> libbpf: support modules in bpf_program__set_attach_target() API
> selftests/bpf: add set_attach_target() API selftest for module target
>
> [...]
Here is the summary with links:
- [bpf-next,1/2] libbpf: support modules in bpf_program__set_attach_target() API
https://git.kernel.org/bpf/bpf-next/c/fe62de310e2b
- [bpf-next,2/2] selftests/bpf: add set_attach_target() API selftest for module target
https://git.kernel.org/bpf/bpf-next/c/2e33f831fccd
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 4+ messages in thread