mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
bpf: Add bpf_list_add to insert node after a given list node
Add a new kfunc bpf_list_add(head, new, prev, meta, off) that inserts 'new' after 'prev' in the BPF linked list. Both must be in the same list; 'prev' must already be in the list. The new node must be an owning reference (e.g. from bpf_obj_new); the kfunc consumes that reference and the node becomes non-owning once inserted. We have added an additional parameter bpf_list_head *head to bpf_list_add, as the verifier requires the head parameter to check whether the lock is being held. Returns 0 on success, -EINVAL if 'prev' is not in a list or 'new' is already in a list (or duplicate insertion). On failure, the kernel drops the passed-in node. Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn> Reviewed-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://lore.kernel.org/r/20260521032306.97118-7-kaitao.cheng@linux.dev Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
e6919ff67c
commit
a3493ca504
|
|
@ -2577,6 +2577,16 @@ __bpf_kfunc int bpf_list_push_back_impl(struct bpf_list_head *head,
|
|||
return bpf_list_push_back(head, node, meta__ign, off);
|
||||
}
|
||||
|
||||
__bpf_kfunc int bpf_list_add(struct bpf_list_head *head, struct bpf_list_node *new,
|
||||
struct bpf_list_node *prev__nonown_allowed,
|
||||
struct btf_struct_meta *meta, u64 off)
|
||||
{
|
||||
struct bpf_list_node_kern *n = (void *)new, *p = (void *)prev__nonown_allowed;
|
||||
struct list_head *prev_ptr = &p->list_head;
|
||||
|
||||
return __bpf_list_add(n, head, &prev_ptr, meta ? meta->record : NULL, off);
|
||||
}
|
||||
|
||||
static struct bpf_list_node *__bpf_list_del(struct bpf_list_head *head,
|
||||
struct list_head *n)
|
||||
{
|
||||
|
|
@ -4756,6 +4766,7 @@ BTF_ID_FLAGS(func, bpf_list_push_front, KF_IMPLICIT_ARGS)
|
|||
BTF_ID_FLAGS(func, bpf_list_push_front_impl)
|
||||
BTF_ID_FLAGS(func, bpf_list_push_back, KF_IMPLICIT_ARGS)
|
||||
BTF_ID_FLAGS(func, bpf_list_push_back_impl)
|
||||
BTF_ID_FLAGS(func, bpf_list_add, KF_IMPLICIT_ARGS)
|
||||
BTF_ID_FLAGS(func, bpf_list_pop_front, KF_ACQUIRE | KF_RET_NULL)
|
||||
BTF_ID_FLAGS(func, bpf_list_pop_back, KF_ACQUIRE | KF_RET_NULL)
|
||||
BTF_ID_FLAGS(func, bpf_list_del, KF_ACQUIRE | KF_RET_NULL)
|
||||
|
|
|
|||
|
|
@ -10959,6 +10959,7 @@ enum special_kfunc_type {
|
|||
KF_bpf_list_push_front,
|
||||
KF_bpf_list_push_back_impl,
|
||||
KF_bpf_list_push_back,
|
||||
KF_bpf_list_add,
|
||||
KF_bpf_list_pop_front,
|
||||
KF_bpf_list_pop_back,
|
||||
KF_bpf_list_del,
|
||||
|
|
@ -11028,6 +11029,7 @@ BTF_ID(func, bpf_list_push_front_impl)
|
|||
BTF_ID(func, bpf_list_push_front)
|
||||
BTF_ID(func, bpf_list_push_back_impl)
|
||||
BTF_ID(func, bpf_list_push_back)
|
||||
BTF_ID(func, bpf_list_add)
|
||||
BTF_ID(func, bpf_list_pop_front)
|
||||
BTF_ID(func, bpf_list_pop_back)
|
||||
BTF_ID(func, bpf_list_del)
|
||||
|
|
@ -11140,7 +11142,8 @@ static bool is_bpf_list_push_kfunc(u32 func_id)
|
|||
return func_id == special_kfunc_list[KF_bpf_list_push_front] ||
|
||||
func_id == special_kfunc_list[KF_bpf_list_push_front_impl] ||
|
||||
func_id == special_kfunc_list[KF_bpf_list_push_back] ||
|
||||
func_id == special_kfunc_list[KF_bpf_list_push_back_impl];
|
||||
func_id == special_kfunc_list[KF_bpf_list_push_back_impl] ||
|
||||
func_id == special_kfunc_list[KF_bpf_list_add];
|
||||
}
|
||||
|
||||
static bool is_bpf_rbtree_add_kfunc(u32 func_id)
|
||||
|
|
@ -19524,8 +19527,11 @@ int bpf_fixup_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
|
|||
int struct_meta_reg = BPF_REG_3;
|
||||
int node_offset_reg = BPF_REG_4;
|
||||
|
||||
/* rbtree_add has extra 'less' arg, so args-to-fixup are in diff regs */
|
||||
if (is_bpf_rbtree_add_kfunc(desc->func_id)) {
|
||||
/* list_add/rbtree_add have an extra arg (prev/less),
|
||||
* so args-to-fixup are in diff regs.
|
||||
*/
|
||||
if (desc->func_id == special_kfunc_list[KF_bpf_list_add] ||
|
||||
is_bpf_rbtree_add_kfunc(desc->func_id)) {
|
||||
struct_meta_reg = BPF_REG_4;
|
||||
node_offset_reg = BPF_REG_5;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user