From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
To: bpf@vger.kernel.org
Cc: "Kumar Kartikeya Dwivedi" <memxor@gmail.com>,
"Alexei Starovoitov" <ast@kernel.org>,
"Daniel Borkmann" <daniel@iogearbox.net>,
"Andrii Nakryiko" <andrii@kernel.org>,
"Martin KaFai Lau" <kafai@fb.com>,
"Song Liu" <songliubraving@fb.com>, "Yonghong Song" <yhs@fb.com>,
"Jesper Dangaard Brouer" <brouer@redhat.com>,
"Toke Høiland-Jørgensen" <toke@redhat.com>,
netdev@vger.kernel.org
Subject: [PATCH bpf-next RFC v1 3/8] libbpf: Support kernel module function calls
Date: Mon, 30 Aug 2021 23:04:19 +0530 [thread overview]
Message-ID: <20210830173424.1385796-4-memxor@gmail.com> (raw)
In-Reply-To: <20210830173424.1385796-1-memxor@gmail.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
---
tools/lib/bpf/bpf.c | 3 ++
tools/lib/bpf/libbpf.c | 71 +++++++++++++++++++++++++++++++--
tools/lib/bpf/libbpf_internal.h | 2 +
3 files changed, 73 insertions(+), 3 deletions(-)
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 2401fad090c5..df2d1ceba146 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -265,6 +265,9 @@ int libbpf__bpf_prog_load(const struct bpf_prog_load_params *load_attr)
attr.line_info_cnt = load_attr->line_info_cnt;
attr.line_info = ptr_to_u64(load_attr->line_info);
+ attr.kfunc_btf_fds = ptr_to_u64(load_attr->kfunc_btf_fds);
+ attr.kfunc_btf_fds_cnt = load_attr->kfunc_btf_fds_cnt;
+
if (load_attr->name)
memcpy(attr.prog_name, load_attr->name,
min(strlen(load_attr->name), (size_t)BPF_OBJ_NAME_LEN - 1));
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 88d8825fc6f6..c4677ef97caa 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -419,6 +419,12 @@ struct extern_desc {
/* local btf_id of the ksym extern's type. */
__u32 type_id;
+ /* offset to be patched in for insn->off,
+ * this is 0 for btf_vmlinux, and index + 1
+ * for module BTF, where index is BTF index in
+ * obj->kfunc_btf_fds.fds array
+ */
+ __u32 offset;
} ksym;
};
};
@@ -515,6 +521,13 @@ struct bpf_object {
void *priv;
bpf_object_clear_priv_t clear_priv;
+ struct {
+ struct hashmap *map;
+ int *fds;
+ size_t cap_cnt;
+ __u32 n_fds;
+ } kfunc_btf_fds;
+
char path[];
};
#define obj_elf_valid(o) ((o)->efile.elf)
@@ -5327,6 +5340,7 @@ bpf_object__relocate_data(struct bpf_object *obj, struct bpf_program *prog)
ext = &obj->externs[relo->sym_off];
insn[0].src_reg = BPF_PSEUDO_KFUNC_CALL;
insn[0].imm = ext->ksym.kernel_btf_id;
+ insn[0].off = ext->ksym.offset;
break;
case RELO_SUBPROG_ADDR:
if (insn[0].src_reg != BPF_PSEUDO_FUNC) {
@@ -6122,6 +6136,11 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt,
load_attr.log_level = prog->log_level;
load_attr.prog_flags = prog->prog_flags;
+ if (prog->obj->kfunc_btf_fds.n_fds) {
+ load_attr.kfunc_btf_fds = prog->obj->kfunc_btf_fds.fds;
+ load_attr.kfunc_btf_fds_cnt = prog->obj->kfunc_btf_fds.n_fds;
+ }
+
if (prog->obj->gen_loader) {
bpf_gen__prog_load(prog->obj->gen_loader, &load_attr,
prog - prog->obj->programs);
@@ -6723,9 +6742,49 @@ static int bpf_object__resolve_ksym_func_btf_id(struct bpf_object *obj,
}
if (kern_btf != obj->btf_vmlinux) {
- pr_warn("extern (func ksym) '%s': function in kernel module is not supported\n",
- ext->name);
- return -ENOTSUP;
+ size_t index;
+ void *value;
+
+ /* Lazy initialize btf->fd index map */
+ if (!obj->kfunc_btf_fds.map) {
+ obj->kfunc_btf_fds.map = hashmap__new(bpf_core_hash_fn, bpf_core_equal_fn,
+ NULL);
+ if (!obj->kfunc_btf_fds.map)
+ return -ENOMEM;
+
+ obj->kfunc_btf_fds.fds = calloc(8, sizeof(*obj->kfunc_btf_fds.fds));
+ if (!obj->kfunc_btf_fds.fds) {
+ hashmap__free(obj->kfunc_btf_fds.map);
+ return -ENOMEM;
+ }
+ obj->kfunc_btf_fds.cap_cnt = 8;
+ }
+
+ if (!hashmap__find(obj->kfunc_btf_fds.map, kern_btf, &value)) {
+ size_t *cap_cnt = &obj->kfunc_btf_fds.cap_cnt;
+ /* Not found, insert BTF fd into slot, and grab next
+ * index from the fd array.
+ */
+ ret = libbpf_ensure_mem((void **)&obj->kfunc_btf_fds.fds,
+ cap_cnt, sizeof(int), obj->kfunc_btf_fds.n_fds + 1);
+ if (ret)
+ return ret;
+ index = obj->kfunc_btf_fds.n_fds++;
+ obj->kfunc_btf_fds.fds[index] = kern_btf_fd;
+ value = (void *)index;
+ ret = hashmap__add(obj->kfunc_btf_fds.map, kern_btf, &value);
+ if (ret)
+ return ret;
+
+ } else {
+ index = (size_t)value;
+ }
+ /* index starts from 0, so shift offset by 1 as offset == 0 is reserved
+ * for btf_vmlinux in the kernel
+ */
+ ext->ksym.offset = index + 1;
+ } else {
+ ext->ksym.offset = 0;
}
kern_func = btf__type_by_id(kern_btf, kfunc_id);
@@ -6901,6 +6960,12 @@ int bpf_object__load_xattr(struct bpf_object_load_attr *attr)
err = bpf_gen__finish(obj->gen_loader);
}
+ /* clean up kfunc_btf */
+ hashmap__free(obj->kfunc_btf_fds.map);
+ obj->kfunc_btf_fds.map = NULL;
+ zfree(&obj->kfunc_btf_fds.fds);
+ obj->kfunc_btf_fds.cap_cnt = obj->kfunc_btf_fds.n_fds = 0;
+
/* clean up module BTFs */
for (i = 0; i < obj->btf_module_cnt; i++) {
close(obj->btf_modules[i].fd);
diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h
index 533b0211f40a..701719d9caaf 100644
--- a/tools/lib/bpf/libbpf_internal.h
+++ b/tools/lib/bpf/libbpf_internal.h
@@ -276,6 +276,8 @@ struct bpf_prog_load_params {
__u32 log_level;
char *log_buf;
size_t log_buf_sz;
+ int *kfunc_btf_fds;
+ __u32 kfunc_btf_fds_cnt;
};
int libbpf__bpf_prog_load(const struct bpf_prog_load_params *load_attr);
--
2.33.0
next prev parent reply other threads:[~2021-08-30 17:34 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-30 17:34 [PATCH bpf-next RFC v1 0/8] Support kernel module function calls from eBPF Kumar Kartikeya Dwivedi
2021-08-30 17:34 ` [PATCH bpf-next RFC v1 1/8] bpf: Introduce BPF support for kernel module function calls Kumar Kartikeya Dwivedi
2021-08-30 20:01 ` Alexei Starovoitov
2021-08-30 17:34 ` [PATCH bpf-next RFC v1 2/8] bpf: Be conservative during verification for invalid kfunc calls Kumar Kartikeya Dwivedi
2021-08-30 17:34 ` Kumar Kartikeya Dwivedi [this message]
2021-09-01 0:55 ` [PATCH bpf-next RFC v1 3/8] libbpf: Support kernel module function calls Andrii Nakryiko
2021-09-01 2:27 ` Kumar Kartikeya Dwivedi
2021-09-01 2:59 ` Alexei Starovoitov
2021-09-01 3:38 ` Andrii Nakryiko
2021-08-30 17:34 ` [PATCH bpf-next RFC v1 4/8] libbpf: Resolve invalid kfunc calls with imm = 0, off = 0 Kumar Kartikeya Dwivedi
2021-09-01 0:35 ` Andrii Nakryiko
2021-08-30 17:34 ` [PATCH bpf-next RFC v1 5/8] tools: Allow specifying base BTF file in resolve_btfids Kumar Kartikeya Dwivedi
2021-08-30 17:34 ` [PATCH bpf-next RFC v1 6/8] bpf: btf: Introduce helpers for dynamic BTF set registration Kumar Kartikeya Dwivedi
2021-08-30 17:34 ` [PATCH bpf-next RFC v1 7/8] bpf: enable TCP congestion control kfunc from modules Kumar Kartikeya Dwivedi
2021-09-01 0:48 ` Andrii Nakryiko
2021-08-30 17:34 ` [PATCH bpf-next RFC v1 8/8] bpf, selftests: Add basic test for module kfunc call Kumar Kartikeya Dwivedi
2021-08-30 20:07 ` Alexei Starovoitov
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=20210830173424.1385796-4-memxor@gmail.com \
--to=memxor@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=brouer@redhat.com \
--cc=daniel@iogearbox.net \
--cc=kafai@fb.com \
--cc=netdev@vger.kernel.org \
--cc=songliubraving@fb.com \
--cc=toke@redhat.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox