bpf: lookup struct_ops types from a given module BTF.
authorKui-Feng Lee <thinker.li@gmail.com>
Fri, 19 Jan 2024 22:49:58 +0000 (14:49 -0800)
committerMartin KaFai Lau <martin.lau@kernel.org>
Wed, 24 Jan 2024 00:37:44 +0000 (16:37 -0800)
This is a preparation for searching for struct_ops types from a specified
module. BTF is always btf_vmlinux now. This patch passes a pointer of BTF
to bpf_struct_ops_find_value() and bpf_struct_ops_find(). Once the new
registration API of struct_ops types is used, other BTFs besides
btf_vmlinux can also be passed to them.

Signed-off-by: Kui-Feng Lee <thinker.li@gmail.com>
Link: https://lore.kernel.org/r/20240119225005.668602-8-thinker.li@gmail.com
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
include/linux/bpf.h
kernel/bpf/bpf_struct_ops.c
kernel/bpf/verifier.c

index 29fcae9fa8ed17e0eff816edd3d0146479fe24ec..86ff8911d7eec8d9da5833494262a607f7f5064d 100644 (file)
@@ -1689,7 +1689,7 @@ struct bpf_struct_ops_desc {
 
 #if defined(CONFIG_BPF_JIT) && defined(CONFIG_BPF_SYSCALL)
 #define BPF_MODULE_OWNER ((void *)((0xeB9FUL << 2) + POISON_POINTER_DELTA))
-const struct bpf_struct_ops_desc *bpf_struct_ops_find(u32 type_id);
+const struct bpf_struct_ops_desc *bpf_struct_ops_find(struct btf *btf, u32 type_id);
 void bpf_struct_ops_init(struct btf *btf, struct bpf_verifier_log *log);
 bool bpf_struct_ops_get(const void *kdata);
 void bpf_struct_ops_put(const void *kdata);
@@ -1734,7 +1734,7 @@ int bpf_struct_ops_test_run(struct bpf_prog *prog, const union bpf_attr *kattr,
 #endif
 void bpf_map_struct_ops_info_fill(struct bpf_map_info *info, struct bpf_map *map);
 #else
-static inline const struct bpf_struct_ops_desc *bpf_struct_ops_find(u32 type_id)
+static inline const struct bpf_struct_ops_desc *bpf_struct_ops_find(struct btf *btf, u32 type_id)
 {
        return NULL;
 }
index 5e98af4fc2e2bbb23872d4cd32880ffb9436efa3..7505f515aac339925fb08de1103f0796f19307e4 100644 (file)
@@ -221,11 +221,11 @@ void bpf_struct_ops_init(struct btf *btf, struct bpf_verifier_log *log)
 extern struct btf *btf_vmlinux;
 
 static const struct bpf_struct_ops_desc *
-bpf_struct_ops_find_value(u32 value_id)
+bpf_struct_ops_find_value(struct btf *btf, u32 value_id)
 {
        unsigned int i;
 
-       if (!value_id || !btf_vmlinux)
+       if (!value_id || !btf)
                return NULL;
 
        for (i = 0; i < ARRAY_SIZE(bpf_struct_ops); i++) {
@@ -236,11 +236,12 @@ bpf_struct_ops_find_value(u32 value_id)
        return NULL;
 }
 
-const struct bpf_struct_ops_desc *bpf_struct_ops_find(u32 type_id)
+const struct bpf_struct_ops_desc *
+bpf_struct_ops_find(struct btf *btf, u32 type_id)
 {
        unsigned int i;
 
-       if (!type_id || !btf_vmlinux)
+       if (!type_id || !btf)
                return NULL;
 
        for (i = 0; i < ARRAY_SIZE(bpf_struct_ops); i++) {
@@ -682,7 +683,7 @@ static struct bpf_map *bpf_struct_ops_map_alloc(union bpf_attr *attr)
        struct bpf_map *map;
        int ret;
 
-       st_ops_desc = bpf_struct_ops_find_value(attr->btf_vmlinux_value_type_id);
+       st_ops_desc = bpf_struct_ops_find_value(btf_vmlinux, attr->btf_vmlinux_value_type_id);
        if (!st_ops_desc)
                return ERR_PTR(-ENOTSUPP);
 
index e279491118b7e04c6489a2f6b49f4c431397ef27..2a0fd2ccdb118d69924268ac5a157858e7312ade 100644 (file)
@@ -20298,7 +20298,7 @@ static int check_struct_ops_btf_id(struct bpf_verifier_env *env)
        }
 
        btf_id = prog->aux->attach_btf_id;
-       st_ops_desc = bpf_struct_ops_find(btf_id);
+       st_ops_desc = bpf_struct_ops_find(btf_vmlinux, btf_id);
        if (!st_ops_desc) {
                verbose(env, "attach_btf_id %u is not a supported struct\n",
                        btf_id);