Future commits adding more callbacks will implement the same pattern of matching module owner of kfunc_btf_id_set, and then operating on data in the struct. Since all call sites in the verifier hold a reference to struct module parameter 'owner', it is safe to release the mutex lock and still reference the struct pointer. This can be consolidated in a common helper given the reference is always held for owner module parameter. Since removal from the list is dependent on module reference dropping to zero, it is safe to assume it is registered as long the caller holds a reference. Signed-off-by: Kumar Kartikeya Dwivedi <memxor@xxxxxxxxx> --- kernel/bpf/btf.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index dbc3ad07e21b..be1082270455 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -6371,22 +6371,35 @@ void unregister_kfunc_btf_id_set(struct kfunc_btf_id_list *l, } EXPORT_SYMBOL_GPL(unregister_kfunc_btf_id_set); -bool bpf_check_mod_kfunc_call(struct kfunc_btf_id_list *klist, u32 kfunc_id, - struct module *owner) +/* Caller must hold reference to module 'owner' */ +struct kfunc_btf_id_set *__get_kfunc_btf_id_set(struct kfunc_btf_id_list *klist, + struct module *owner) { - struct kfunc_btf_id_set *s; + struct kfunc_btf_id_set *s, *ret = NULL; if (!owner) - return false; + return NULL; mutex_lock(&klist->mutex); list_for_each_entry(s, &klist->list, list) { - if (s->owner == owner && btf_id_set_contains(s->set, kfunc_id)) { - mutex_unlock(&klist->mutex); - return true; + if (s->owner == owner) { + ret = s; + break; } } mutex_unlock(&klist->mutex); - return false; + return ret; +} + +bool bpf_check_mod_kfunc_call(struct kfunc_btf_id_list *klist, u32 kfunc_id, + struct module *owner) +{ + struct kfunc_btf_id_set *s; + bool ret = false; + + s = __get_kfunc_btf_id_set(klist, owner); + if (s) + ret = btf_id_set_contains(s->set, kfunc_id); + return ret; } #endif -- 2.33.1