Skip to content

Commit 7d4c652

Browse files
committed
BTF_ID_LIST_SIZE
1 parent c81a0c3 commit 7d4c652

File tree

2 files changed

+35
-31
lines changed

2 files changed

+35
-31
lines changed

include/linux/btf_ids.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,15 @@ asm( \
9797
__BTF_ID_LIST(name, local) \
9898
extern u32 name[];
9999

100+
/* The BTF_ID_LIST_END macro may be used to denote an end
101+
* of a BTF_ID_LIST. This enables calculation of the list
102+
* size with BTF_ID_LIST_SIZE.
103+
*/
104+
#define BTF_ID_LIST_END(name) \
105+
BTF_ID_LIST(name##__end)
106+
#define BTF_ID_LIST_SIZE(name) \
107+
(name##__end - name)
108+
100109
#define BTF_ID_LIST_GLOBAL(name, n) \
101110
__BTF_ID_LIST(name, globl)
102111

kernel/bpf/verifier.c

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3249,43 +3249,39 @@ static struct btf *find_kfunc_desc_btf(struct bpf_verifier_env *env, s16 offset)
32493249
return btf_vmlinux ?: ERR_PTR(-ENOENT);
32503250
}
32513251

3252-
#define KF_IMPL_SUFFIX "_impl"
3252+
/* magic_kfuncs is used as a list of (foo, foo_impl) pairs
3253+
*/
3254+
BTF_ID_LIST(magic_kfuncs)
3255+
BTF_ID(func, bpf_wq_set_callback)
3256+
BTF_ID(func, bpf_wq_set_callback_impl)
3257+
BTF_ID_LIST_END(magic_kfuncs)
32533258

3254-
static s32 lookup_magic_kfunc_by_impl(struct btf *desc_btf, const char *impl_name, const struct bpf_prog *prog)
3259+
static s32 magic_kfunc_by_impl(s32 impl_func_id)
32553260
{
3256-
char name[KSYM_SYMBOL_LEN];
3257-
s32 func_id;
3258-
u32 *flags;
32593261
int i;
3262+
for (i = 1; i < BTF_ID_LIST_SIZE(magic_kfuncs); i += 2) {
3263+
if (magic_kfuncs[i] == impl_func_id)
3264+
return magic_kfuncs[i - 1];
3265+
}
3266+
return -ENOENT;
3267+
}
32603268

3261-
if (!str_match_suffix(impl_name, KF_IMPL_SUFFIX))
3262-
return -ENOENT;
3263-
3264-
i = strlen(impl_name) - strlen(KF_IMPL_SUFFIX);
3265-
strncpy(name, impl_name, i);
3266-
name[i] = '\0';
3267-
3268-
func_id = btf_find_by_name_kind(desc_btf, name, BTF_KIND_FUNC);
3269-
if (func_id < 0)
3270-
return func_id;
3271-
3272-
flags = btf_kfunc_id_set_contains(desc_btf, func_id, prog);
3273-
if (flags && KF_MAGIC_ARGS & *flags)
3274-
return func_id;
3275-
3269+
static s32 impl_by_magic_kfunc(s32 func_id)
3270+
{
3271+
int i;
3272+
for (i = 0; i < BTF_ID_LIST_SIZE(magic_kfuncs); i += 2) {
3273+
if (magic_kfuncs[i] == func_id)
3274+
return magic_kfuncs[i + 1];
3275+
}
32763276
return -ENOENT;
32773277
}
32783278

3279-
static const struct btf_type *find_magic_kfunc_proto(struct btf *desc_btf, const char *func_name)
3279+
static const struct btf_type *find_magic_kfunc_proto(struct btf *desc_btf, s32 func_id)
32803280
{
32813281
const struct btf_type *impl_func, *func_proto;
3282-
char impl_name[KSYM_SYMBOL_LEN];
32833282
u32 impl_func_id;
32843283

3285-
strncpy(impl_name, func_name, strlen(func_name));
3286-
strncat(impl_name, KF_IMPL_SUFFIX, strlen(KF_IMPL_SUFFIX));
3287-
3288-
impl_func_id = btf_find_by_name_kind(desc_btf, impl_name, BTF_KIND_FUNC);
3284+
impl_func_id = impl_by_magic_kfunc(func_id);
32893285
if (impl_func_id < 0)
32903286
return NULL;
32913287

@@ -3300,7 +3296,6 @@ static const struct btf_type *find_magic_kfunc_proto(struct btf *desc_btf, const
33003296
return func_proto;
33013297
}
33023298

3303-
33043299
static int add_kfunc_call(struct bpf_verifier_env *env, u32 func_id, s16 offset)
33053300
{
33063301
const struct btf_type *func, *tmp_func, *func_proto;
@@ -3402,7 +3397,7 @@ static int add_kfunc_call(struct bpf_verifier_env *env, u32 func_id, s16 offset)
34023397

34033398
/* This may be an _impl kfunc with KF_MAGIC_ARGS counterpart */
34043399
if (unlikely(!addr && !kfunc_flags)) {
3405-
tmp_func_id = lookup_magic_kfunc_by_impl(desc_btf, func_name, env->prog);
3400+
tmp_func_id = magic_kfunc_by_impl(func_id);
34063401
if (tmp_func_id < 0)
34073402
return -EACCES;
34083403
tmp_func = btf_type_by_id(desc_btf, tmp_func_id);
@@ -3419,7 +3414,7 @@ static int add_kfunc_call(struct bpf_verifier_env *env, u32 func_id, s16 offset)
34193414
}
34203415

34213416
if (unlikely(KF_MAGIC_ARGS & *kfunc_flags)) {
3422-
func_proto = find_magic_kfunc_proto(desc_btf, func_name);
3417+
func_proto = find_magic_kfunc_proto(desc_btf, func_id);
34233418
if (!func_proto) {
34243419
verbose(env, "cannot find _impl proto for kernel function %s\n",
34253420
func_name);
@@ -13760,7 +13755,7 @@ static int fetch_kfunc_meta(struct bpf_verifier_env *env,
1376013755
/* An _impl kfunc with KF_MAGIC_ARGS counterpart
1376113756
* does not have its own kfunc flags.
1376213757
*/
13763-
tmp_func_id = lookup_magic_kfunc_by_impl(desc_btf, func_name, env->prog);
13758+
tmp_func_id = magic_kfunc_by_impl(func_id);
1376413759
if (func_id < 0)
1376513760
return -EACCES;
1376613761
kfunc_flags = btf_kfunc_id_set_contains(desc_btf, tmp_func_id, env->prog);
@@ -13770,7 +13765,7 @@ static int fetch_kfunc_meta(struct bpf_verifier_env *env,
1377013765
/* An actual func_proto of a kfunc with KF_MAGIC_ARGS flag
1377113766
* can be found through the corresponding _impl kfunc.
1377213767
*/
13773-
func_proto = find_magic_kfunc_proto(desc_btf, func_name);
13768+
func_proto = find_magic_kfunc_proto(desc_btf, func_id);
1377413769
}
1377513770

1377613771
if (!func_proto)

0 commit comments

Comments
 (0)