Skip to content

Commit 4c5763e

Browse files
ThinkerYzu1Martin KaFai Lau
authored andcommitted
bpf, net: introduce bpf_struct_ops_desc.
Move some of members of bpf_struct_ops to bpf_struct_ops_desc. type_id is unavailabe in bpf_struct_ops anymore. Modules should get it from the btf received by kmod's init function. Cc: netdev@vger.kernel.org Signed-off-by: Kui-Feng Lee <thinker.li@gmail.com> Link: https://lore.kernel.org/r/20240119225005.668602-4-thinker.li@gmail.com Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
1 parent 9567839 commit 4c5763e

File tree

5 files changed

+73
-49
lines changed

5 files changed

+73
-49
lines changed

include/linux/bpf.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1673,18 +1673,23 @@ struct bpf_struct_ops {
16731673
void (*unreg)(void *kdata);
16741674
int (*update)(void *kdata, void *old_kdata);
16751675
int (*validate)(void *kdata);
1676-
const struct btf_type *type;
1677-
const struct btf_type *value_type;
1676+
void *cfi_stubs;
16781677
const char *name;
16791678
struct btf_func_model func_models[BPF_STRUCT_OPS_MAX_NR_MEMBERS];
1679+
};
1680+
1681+
struct bpf_struct_ops_desc {
1682+
struct bpf_struct_ops *st_ops;
1683+
1684+
const struct btf_type *type;
1685+
const struct btf_type *value_type;
16801686
u32 type_id;
16811687
u32 value_id;
1682-
void *cfi_stubs;
16831688
};
16841689

16851690
#if defined(CONFIG_BPF_JIT) && defined(CONFIG_BPF_SYSCALL)
16861691
#define BPF_MODULE_OWNER ((void *)((0xeB9FUL << 2) + POISON_POINTER_DELTA))
1687-
const struct bpf_struct_ops *bpf_struct_ops_find(u32 type_id);
1692+
const struct bpf_struct_ops_desc *bpf_struct_ops_find(u32 type_id);
16881693
void bpf_struct_ops_init(struct btf *btf, struct bpf_verifier_log *log);
16891694
bool bpf_struct_ops_get(const void *kdata);
16901695
void bpf_struct_ops_put(const void *kdata);
@@ -1728,7 +1733,7 @@ int bpf_struct_ops_test_run(struct bpf_prog *prog, const union bpf_attr *kattr,
17281733
union bpf_attr __user *uattr);
17291734
#endif
17301735
#else
1731-
static inline const struct bpf_struct_ops *bpf_struct_ops_find(u32 type_id)
1736+
static inline const struct bpf_struct_ops_desc *bpf_struct_ops_find(u32 type_id)
17321737
{
17331738
return NULL;
17341739
}

kernel/bpf/bpf_struct_ops.c

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ struct bpf_struct_ops_value {
3232
struct bpf_struct_ops_map {
3333
struct bpf_map map;
3434
struct rcu_head rcu;
35-
const struct bpf_struct_ops *st_ops;
35+
const struct bpf_struct_ops_desc *st_ops_desc;
3636
/* protect map_update */
3737
struct mutex lock;
3838
/* link has all the bpf_links that is populated
@@ -92,9 +92,9 @@ enum {
9292
__NR_BPF_STRUCT_OPS_TYPE,
9393
};
9494

95-
static struct bpf_struct_ops * const bpf_struct_ops[] = {
95+
static struct bpf_struct_ops_desc bpf_struct_ops[] = {
9696
#define BPF_STRUCT_OPS_TYPE(_name) \
97-
[BPF_STRUCT_OPS_TYPE_##_name] = &bpf_##_name,
97+
[BPF_STRUCT_OPS_TYPE_##_name] = { .st_ops = &bpf_##_name },
9898
#include "bpf_struct_ops_types.h"
9999
#undef BPF_STRUCT_OPS_TYPE
100100
};
@@ -115,10 +115,11 @@ enum {
115115
IDX_MODULE_ID,
116116
};
117117

118-
static void bpf_struct_ops_init_one(struct bpf_struct_ops *st_ops,
119-
struct btf *btf,
120-
struct bpf_verifier_log *log)
118+
static void bpf_struct_ops_desc_init(struct bpf_struct_ops_desc *st_ops_desc,
119+
struct btf *btf,
120+
struct bpf_verifier_log *log)
121121
{
122+
struct bpf_struct_ops *st_ops = st_ops_desc->st_ops;
122123
const struct btf_member *member;
123124
const struct btf_type *t;
124125
s32 type_id, value_id;
@@ -190,18 +191,18 @@ static void bpf_struct_ops_init_one(struct bpf_struct_ops *st_ops,
190191
pr_warn("Error in init bpf_struct_ops %s\n",
191192
st_ops->name);
192193
} else {
193-
st_ops->type_id = type_id;
194-
st_ops->type = t;
195-
st_ops->value_id = value_id;
196-
st_ops->value_type = btf_type_by_id(btf,
197-
value_id);
194+
st_ops_desc->type_id = type_id;
195+
st_ops_desc->type = t;
196+
st_ops_desc->value_id = value_id;
197+
st_ops_desc->value_type = btf_type_by_id(btf,
198+
value_id);
198199
}
199200
}
200201
}
201202

202203
void bpf_struct_ops_init(struct btf *btf, struct bpf_verifier_log *log)
203204
{
204-
struct bpf_struct_ops *st_ops;
205+
struct bpf_struct_ops_desc *st_ops_desc;
205206
u32 i;
206207

207208
/* Ensure BTF type is emitted for "struct bpf_struct_ops_##_name" */
@@ -210,14 +211,14 @@ void bpf_struct_ops_init(struct btf *btf, struct bpf_verifier_log *log)
210211
#undef BPF_STRUCT_OPS_TYPE
211212

212213
for (i = 0; i < ARRAY_SIZE(bpf_struct_ops); i++) {
213-
st_ops = bpf_struct_ops[i];
214-
bpf_struct_ops_init_one(st_ops, btf, log);
214+
st_ops_desc = &bpf_struct_ops[i];
215+
bpf_struct_ops_desc_init(st_ops_desc, btf, log);
215216
}
216217
}
217218

218219
extern struct btf *btf_vmlinux;
219220

220-
static const struct bpf_struct_ops *
221+
static const struct bpf_struct_ops_desc *
221222
bpf_struct_ops_find_value(u32 value_id)
222223
{
223224
unsigned int i;
@@ -226,23 +227,23 @@ bpf_struct_ops_find_value(u32 value_id)
226227
return NULL;
227228

228229
for (i = 0; i < ARRAY_SIZE(bpf_struct_ops); i++) {
229-
if (bpf_struct_ops[i]->value_id == value_id)
230-
return bpf_struct_ops[i];
230+
if (bpf_struct_ops[i].value_id == value_id)
231+
return &bpf_struct_ops[i];
231232
}
232233

233234
return NULL;
234235
}
235236

236-
const struct bpf_struct_ops *bpf_struct_ops_find(u32 type_id)
237+
const struct bpf_struct_ops_desc *bpf_struct_ops_find(u32 type_id)
237238
{
238239
unsigned int i;
239240

240241
if (!type_id || !btf_vmlinux)
241242
return NULL;
242243

243244
for (i = 0; i < ARRAY_SIZE(bpf_struct_ops); i++) {
244-
if (bpf_struct_ops[i]->type_id == type_id)
245-
return bpf_struct_ops[i];
245+
if (bpf_struct_ops[i].type_id == type_id)
246+
return &bpf_struct_ops[i];
246247
}
247248

248249
return NULL;
@@ -302,7 +303,7 @@ static void *bpf_struct_ops_map_lookup_elem(struct bpf_map *map, void *key)
302303

303304
static void bpf_struct_ops_map_put_progs(struct bpf_struct_ops_map *st_map)
304305
{
305-
const struct btf_type *t = st_map->st_ops->type;
306+
const struct btf_type *t = st_map->st_ops_desc->type;
306307
u32 i;
307308

308309
for (i = 0; i < btf_type_vlen(t); i++) {
@@ -382,11 +383,12 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
382383
void *value, u64 flags)
383384
{
384385
struct bpf_struct_ops_map *st_map = (struct bpf_struct_ops_map *)map;
385-
const struct bpf_struct_ops *st_ops = st_map->st_ops;
386+
const struct bpf_struct_ops_desc *st_ops_desc = st_map->st_ops_desc;
387+
const struct bpf_struct_ops *st_ops = st_ops_desc->st_ops;
386388
struct bpf_struct_ops_value *uvalue, *kvalue;
387389
const struct btf_type *module_type;
388390
const struct btf_member *member;
389-
const struct btf_type *t = st_ops->type;
391+
const struct btf_type *t = st_ops_desc->type;
390392
struct bpf_tramp_links *tlinks;
391393
void *udata, *kdata;
392394
int prog_fd, err;
@@ -399,7 +401,7 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
399401
if (*(u32 *)key != 0)
400402
return -E2BIG;
401403

402-
err = check_zero_holes(st_ops->value_type, value);
404+
err = check_zero_holes(st_ops_desc->value_type, value);
403405
if (err)
404406
return err;
405407

@@ -492,7 +494,7 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
492494
}
493495

494496
if (prog->type != BPF_PROG_TYPE_STRUCT_OPS ||
495-
prog->aux->attach_btf_id != st_ops->type_id ||
497+
prog->aux->attach_btf_id != st_ops_desc->type_id ||
496498
prog->expected_attach_type != i) {
497499
bpf_prog_put(prog);
498500
err = -EINVAL;
@@ -588,7 +590,7 @@ static long bpf_struct_ops_map_delete_elem(struct bpf_map *map, void *key)
588590
BPF_STRUCT_OPS_STATE_TOBEFREE);
589591
switch (prev_state) {
590592
case BPF_STRUCT_OPS_STATE_INUSE:
591-
st_map->st_ops->unreg(&st_map->kvalue.data);
593+
st_map->st_ops_desc->st_ops->unreg(&st_map->kvalue.data);
592594
bpf_map_put(map);
593595
return 0;
594596
case BPF_STRUCT_OPS_STATE_TOBEFREE:
@@ -669,22 +671,22 @@ static int bpf_struct_ops_map_alloc_check(union bpf_attr *attr)
669671

670672
static struct bpf_map *bpf_struct_ops_map_alloc(union bpf_attr *attr)
671673
{
672-
const struct bpf_struct_ops *st_ops;
674+
const struct bpf_struct_ops_desc *st_ops_desc;
673675
size_t st_map_size;
674676
struct bpf_struct_ops_map *st_map;
675677
const struct btf_type *t, *vt;
676678
struct bpf_map *map;
677679
int ret;
678680

679-
st_ops = bpf_struct_ops_find_value(attr->btf_vmlinux_value_type_id);
680-
if (!st_ops)
681+
st_ops_desc = bpf_struct_ops_find_value(attr->btf_vmlinux_value_type_id);
682+
if (!st_ops_desc)
681683
return ERR_PTR(-ENOTSUPP);
682684

683-
vt = st_ops->value_type;
685+
vt = st_ops_desc->value_type;
684686
if (attr->value_size != vt->size)
685687
return ERR_PTR(-EINVAL);
686688

687-
t = st_ops->type;
689+
t = st_ops_desc->type;
688690

689691
st_map_size = sizeof(*st_map) +
690692
/* kvalue stores the
@@ -696,7 +698,7 @@ static struct bpf_map *bpf_struct_ops_map_alloc(union bpf_attr *attr)
696698
if (!st_map)
697699
return ERR_PTR(-ENOMEM);
698700

699-
st_map->st_ops = st_ops;
701+
st_map->st_ops_desc = st_ops_desc;
700702
map = &st_map->map;
701703

702704
ret = bpf_jit_charge_modmem(PAGE_SIZE);
@@ -733,8 +735,8 @@ static struct bpf_map *bpf_struct_ops_map_alloc(union bpf_attr *attr)
733735
static u64 bpf_struct_ops_map_mem_usage(const struct bpf_map *map)
734736
{
735737
struct bpf_struct_ops_map *st_map = (struct bpf_struct_ops_map *)map;
736-
const struct bpf_struct_ops *st_ops = st_map->st_ops;
737-
const struct btf_type *vt = st_ops->value_type;
738+
const struct bpf_struct_ops_desc *st_ops_desc = st_map->st_ops_desc;
739+
const struct btf_type *vt = st_ops_desc->value_type;
738740
u64 usage;
739741

740742
usage = sizeof(*st_map) +
@@ -808,7 +810,7 @@ static void bpf_struct_ops_map_link_dealloc(struct bpf_link *link)
808810
/* st_link->map can be NULL if
809811
* bpf_struct_ops_link_create() fails to register.
810812
*/
811-
st_map->st_ops->unreg(&st_map->kvalue.data);
813+
st_map->st_ops_desc->st_ops->unreg(&st_map->kvalue.data);
812814
bpf_map_put(&st_map->map);
813815
}
814816
kfree(st_link);
@@ -855,7 +857,7 @@ static int bpf_struct_ops_map_link_update(struct bpf_link *link, struct bpf_map
855857
if (!bpf_struct_ops_valid_to_reg(new_map))
856858
return -EINVAL;
857859

858-
if (!st_map->st_ops->update)
860+
if (!st_map->st_ops_desc->st_ops->update)
859861
return -EOPNOTSUPP;
860862

861863
mutex_lock(&update_mutex);
@@ -868,12 +870,12 @@ static int bpf_struct_ops_map_link_update(struct bpf_link *link, struct bpf_map
868870

869871
old_st_map = container_of(old_map, struct bpf_struct_ops_map, map);
870872
/* The new and old struct_ops must be the same type. */
871-
if (st_map->st_ops != old_st_map->st_ops) {
873+
if (st_map->st_ops_desc != old_st_map->st_ops_desc) {
872874
err = -EINVAL;
873875
goto err_out;
874876
}
875877

876-
err = st_map->st_ops->update(st_map->kvalue.data, old_st_map->kvalue.data);
878+
err = st_map->st_ops_desc->st_ops->update(st_map->kvalue.data, old_st_map->kvalue.data);
877879
if (err)
878880
goto err_out;
879881

@@ -924,7 +926,7 @@ int bpf_struct_ops_link_create(union bpf_attr *attr)
924926
if (err)
925927
goto err_out;
926928

927-
err = st_map->st_ops->reg(st_map->kvalue.data);
929+
err = st_map->st_ops_desc->st_ops->reg(st_map->kvalue.data);
928930
if (err) {
929931
bpf_link_cleanup(&link_primer);
930932
link = NULL;

kernel/bpf/verifier.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20285,6 +20285,7 @@ static void print_verification_stats(struct bpf_verifier_env *env)
2028520285
static int check_struct_ops_btf_id(struct bpf_verifier_env *env)
2028620286
{
2028720287
const struct btf_type *t, *func_proto;
20288+
const struct bpf_struct_ops_desc *st_ops_desc;
2028820289
const struct bpf_struct_ops *st_ops;
2028920290
const struct btf_member *member;
2029020291
struct bpf_prog *prog = env->prog;
@@ -20297,14 +20298,15 @@ static int check_struct_ops_btf_id(struct bpf_verifier_env *env)
2029720298
}
2029820299

2029920300
btf_id = prog->aux->attach_btf_id;
20300-
st_ops = bpf_struct_ops_find(btf_id);
20301-
if (!st_ops) {
20301+
st_ops_desc = bpf_struct_ops_find(btf_id);
20302+
if (!st_ops_desc) {
2030220303
verbose(env, "attach_btf_id %u is not a supported struct\n",
2030320304
btf_id);
2030420305
return -ENOTSUPP;
2030520306
}
20307+
st_ops = st_ops_desc->st_ops;
2030620308

20307-
t = st_ops->type;
20309+
t = st_ops_desc->type;
2030820310
member_idx = prog->expected_attach_type;
2030920311
if (member_idx >= btf_type_vlen(t)) {
2031020312
verbose(env, "attach to invalid member idx %u of struct %s\n",

net/bpf/bpf_dummy_struct_ops.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ struct bpf_dummy_ops_test_args {
2222
struct bpf_dummy_ops_state state;
2323
};
2424

25+
static struct btf *bpf_dummy_ops_btf;
26+
2527
static struct bpf_dummy_ops_test_args *
2628
dummy_ops_init_args(const union bpf_attr *kattr, unsigned int nr)
2729
{
@@ -90,9 +92,15 @@ int bpf_struct_ops_test_run(struct bpf_prog *prog, const union bpf_attr *kattr,
9092
void *image = NULL;
9193
unsigned int op_idx;
9294
int prog_ret;
95+
s32 type_id;
9396
int err;
9497

95-
if (prog->aux->attach_btf_id != st_ops->type_id)
98+
type_id = btf_find_by_name_kind(bpf_dummy_ops_btf,
99+
bpf_bpf_dummy_ops.name,
100+
BTF_KIND_STRUCT);
101+
if (type_id < 0)
102+
return -EINVAL;
103+
if (prog->aux->attach_btf_id != type_id)
96104
return -EOPNOTSUPP;
97105

98106
func_proto = prog->aux->attach_func_proto;
@@ -148,6 +156,7 @@ int bpf_struct_ops_test_run(struct bpf_prog *prog, const union bpf_attr *kattr,
148156

149157
static int bpf_dummy_init(struct btf *btf)
150158
{
159+
bpf_dummy_ops_btf = btf;
151160
return 0;
152161
}
153162

net/ipv4/bpf_tcp_ca.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ static u32 unsupported_ops[] = {
2020

2121
static const struct btf_type *tcp_sock_type;
2222
static u32 tcp_sock_id, sock_id;
23+
static const struct btf_type *tcp_congestion_ops_type;
2324

2425
static int bpf_tcp_ca_init(struct btf *btf)
2526
{
@@ -36,6 +37,11 @@ static int bpf_tcp_ca_init(struct btf *btf)
3637
tcp_sock_id = type_id;
3738
tcp_sock_type = btf_type_by_id(btf, tcp_sock_id);
3839

40+
type_id = btf_find_by_name_kind(btf, "tcp_congestion_ops", BTF_KIND_STRUCT);
41+
if (type_id < 0)
42+
return -EINVAL;
43+
tcp_congestion_ops_type = btf_type_by_id(btf, type_id);
44+
3945
return 0;
4046
}
4147

@@ -149,7 +155,7 @@ static u32 prog_ops_moff(const struct bpf_prog *prog)
149155
u32 midx;
150156

151157
midx = prog->expected_attach_type;
152-
t = bpf_tcp_congestion_ops.type;
158+
t = tcp_congestion_ops_type;
153159
m = &btf_type_member(t)[midx];
154160

155161
return __btf_member_bit_offset(t, m) / 8;

0 commit comments

Comments
 (0)