From: thinker.li@gmail.com
To: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev,
song@kernel.org, kernel-team@meta.com, andrii@kernel.org,
drosen@google.com
Cc: sinquersw@gmail.com, kuifeng@meta.com,
Kui-Feng Lee <thinker.li@gmail.com>
Subject: [PATCH bpf-next v5 5/9] bpf: pass attached BTF to the bpf_struct_ops subsystem
Date: Tue, 17 Oct 2023 09:23:02 -0700 [thread overview]
Message-ID: <20231017162306.176586-6-thinker.li@gmail.com> (raw)
In-Reply-To: <20231017162306.176586-1-thinker.li@gmail.com>
From: Kui-Feng Lee <thinker.li@gmail.com>
Giving a BTF, the bpf_struct_ops knows the right place to look up type info
associated with a type ID. This enables a user space program to load a
struct_ops object linked to a struct_ops type defined by a module, by
providing the module BTF (fd).
The bpf_prog includes attach_btf in aux which is passed along with the
bpf_attr when loading the program. The purpose of attach_btf is to
determine the btf type of attach_btf_id. The attach_btf_id is then used to
identify the traced function for a trace program. In the case of struct_ops
programs, it is used to identify the struct_ops type of the struct_ops
object that a program is attached to.
Signed-off-by: Kui-Feng Lee <thinker.li@gmail.com>
---
include/uapi/linux/bpf.h | 5 +++++
kernel/bpf/bpf_struct_ops.c | 34 +++++++++++++++++++++++++++-------
kernel/bpf/syscall.c | 2 +-
kernel/bpf/verifier.c | 4 +++-
tools/include/uapi/linux/bpf.h | 5 +++++
5 files changed, 41 insertions(+), 9 deletions(-)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 73b155e52204..b5ef22f65f35 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -1390,6 +1390,11 @@ union bpf_attr {
* to using 5 hash functions).
*/
__u64 map_extra;
+
+ __u32 value_type_btf_obj_fd; /* fd pointing to a BTF
+ * type data for
+ * btf_vmlinux_value_type_id.
+ */
};
struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */
diff --git a/kernel/bpf/bpf_struct_ops.c b/kernel/bpf/bpf_struct_ops.c
index 69703584fa4a..60445ff32275 100644
--- a/kernel/bpf/bpf_struct_ops.c
+++ b/kernel/bpf/bpf_struct_ops.c
@@ -677,6 +677,7 @@ static void __bpf_struct_ops_map_free(struct bpf_map *map)
bpf_jit_uncharge_modmem(PAGE_SIZE);
}
bpf_map_area_free(st_map->uvalue);
+ btf_put(st_map->st_ops->btf);
module_put(st_map->st_ops->owner);
bpf_map_area_free(st_map);
}
@@ -718,23 +719,36 @@ static struct bpf_map *bpf_struct_ops_map_alloc(union bpf_attr *attr)
struct bpf_struct_ops_map *st_map;
const struct btf_type *t, *vt;
struct bpf_map *map;
+ struct btf *btf;
int ret;
- st_ops = bpf_struct_ops_find_value(btf_vmlinux, attr->btf_vmlinux_value_type_id);
- if (!st_ops)
+ if (attr->value_type_btf_obj_fd) {
+ btf = btf_get_by_fd(attr->value_type_btf_obj_fd);
+ if (IS_ERR(btf))
+ return ERR_PTR(PTR_ERR(btf));
+ } else {
+ btf = btf_vmlinux;
+ btf_get(btf);
+ }
+ st_ops = bpf_struct_ops_find_value(btf, attr->btf_vmlinux_value_type_id);
+ if (!st_ops) {
+ btf_put(btf);
return ERR_PTR(-ENOTSUPP);
+ }
/* If st_ops->owner is NULL, it means the struct_ops is
* statically defined in the kernel. We don't need to
* take a refcount on it.
*/
- if (st_ops->owner && !btf_try_get_module(st_ops->btf))
+ if (st_ops->owner && !btf_try_get_module(st_ops->btf)) {
+ btf_put(btf);
return ERR_PTR(-EINVAL);
+ }
vt = st_ops->value_type;
if (attr->value_size != vt->size) {
- module_put(st_ops->owner);
- return ERR_PTR(-EINVAL);
+ ret = -EINVAL;
+ goto errout;
}
t = st_ops->type;
@@ -747,8 +761,8 @@ static struct bpf_map *bpf_struct_ops_map_alloc(union bpf_attr *attr)
st_map = bpf_map_area_alloc(st_map_size, NUMA_NO_NODE);
if (!st_map) {
- module_put(st_ops->owner);
- return ERR_PTR(-ENOMEM);
+ ret = -ENOMEM;
+ goto errout;
}
st_map->st_ops = st_ops;
@@ -784,6 +798,12 @@ static struct bpf_map *bpf_struct_ops_map_alloc(union bpf_attr *attr)
bpf_map_init_from_attr(map, attr);
return map;
+
+errout:
+ btf_put(btf);
+ module_put(st_ops->owner);
+
+ return ERR_PTR(ret);
}
static u64 bpf_struct_ops_map_mem_usage(const struct bpf_map *map)
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 85c1d908f70f..5daf8a2c2bba 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -1097,7 +1097,7 @@ static int map_check_btf(struct bpf_map *map, const struct btf *btf,
return ret;
}
-#define BPF_MAP_CREATE_LAST_FIELD map_extra
+#define BPF_MAP_CREATE_LAST_FIELD value_type_btf_obj_fd
/* called via syscall */
static int map_create(union bpf_attr *attr)
{
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 6564a03c425d..ce4df24eb03b 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -19623,6 +19623,7 @@ static int check_struct_ops_btf_id(struct bpf_verifier_env *env)
const struct btf_member *member;
struct bpf_prog *prog = env->prog;
u32 btf_id, member_idx;
+ struct btf *btf;
const char *mname;
if (!prog->gpl_compatible) {
@@ -19630,8 +19631,9 @@ static int check_struct_ops_btf_id(struct bpf_verifier_env *env)
return -EINVAL;
}
+ btf = prog->aux->attach_btf;
btf_id = prog->aux->attach_btf_id;
- st_ops = bpf_struct_ops_find(btf_vmlinux, btf_id);
+ st_ops = bpf_struct_ops_find(btf, btf_id);
if (!st_ops) {
verbose(env, "attach_btf_id %u is not a supported struct\n",
btf_id);
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 73b155e52204..b5ef22f65f35 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -1390,6 +1390,11 @@ union bpf_attr {
* to using 5 hash functions).
*/
__u64 map_extra;
+
+ __u32 value_type_btf_obj_fd; /* fd pointing to a BTF
+ * type data for
+ * btf_vmlinux_value_type_id.
+ */
};
struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */
--
2.34.1
next prev parent reply other threads:[~2023-10-17 16:23 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-17 16:22 [PATCH bpf-next v5 0/9] Registrating struct_ops types from modules thinker.li
2023-10-17 16:22 ` [PATCH bpf-next v5 1/9] bpf: refactory struct_ops type initialization to a function thinker.li
2023-10-17 16:22 ` [PATCH bpf-next v5 2/9] bpf: add struct_ops_tab to btf thinker.li
2023-10-19 0:00 ` Martin KaFai Lau
2023-10-19 0:33 ` Kui-Feng Lee
2023-10-19 2:28 ` Martin KaFai Lau
2023-10-19 16:15 ` Kui-Feng Lee
2023-10-17 16:23 ` [PATCH bpf-next v5 3/9] bpf: hold module for bpf_struct_ops_map thinker.li
2023-10-19 0:36 ` Martin KaFai Lau
2023-10-19 16:29 ` Kui-Feng Lee
2023-10-20 5:07 ` Kui-Feng Lee
2023-10-20 21:37 ` Martin KaFai Lau
2023-10-20 22:28 ` Kui-Feng Lee
2023-10-17 16:23 ` [PATCH bpf-next v5 4/9] bpf: validate value_type thinker.li
2023-10-17 16:23 ` thinker.li [this message]
2023-10-17 16:23 ` [PATCH bpf-next v5 6/9] bpf, net: switch to dynamic registration thinker.li
2023-10-19 1:49 ` Martin KaFai Lau
2023-10-20 15:12 ` Kui-Feng Lee
2023-10-20 17:53 ` Kui-Feng Lee
2023-10-17 16:23 ` [PATCH bpf-next v5 7/9] libbpf: Find correct module BTFs for struct_ops maps and progs thinker.li
2023-10-17 21:49 ` Andrii Nakryiko
2023-10-18 2:25 ` Kui-Feng Lee
2023-10-19 2:43 ` Martin KaFai Lau
2023-10-19 16:31 ` Kui-Feng Lee
2023-10-17 16:23 ` [PATCH bpf-next v5 8/9] bpf: export btf_ctx_access to modules thinker.li
2023-10-17 16:23 ` [PATCH bpf-next v5 9/9] selftests/bpf: test case for register_bpf_struct_ops() thinker.li
2023-10-17 18:03 ` kernel test robot
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=20231017162306.176586-6-thinker.li@gmail.com \
--to=thinker.li@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=drosen@google.com \
--cc=kernel-team@meta.com \
--cc=kuifeng@meta.com \
--cc=martin.lau@linux.dev \
--cc=sinquersw@gmail.com \
--cc=song@kernel.org \
/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.