* [PATCH bpf-next v1 0/8] resolve_btfids: Discover kfuncs from BTF ID sets
@ 2026-07-22 23:35 Ihor Solodrai
2026-07-22 23:35 ` [PATCH bpf-next v1 1/8] resolve_btfids: Implement generic ensure_mem() to grow arrays Ihor Solodrai
` (7 more replies)
0 siblings, 8 replies; 21+ messages in thread
From: Ihor Solodrai @ 2026-07-22 23:35 UTC (permalink / raw)
To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Kumar Kartikeya Dwivedi
Cc: Benjamin Tissoires, Jiri Kosina, Emil Tsalapatis, Jiri Olsa, bpf,
linux-input, kernel-team
This series develops resolve_btfids in preparation for bringing
kernel-specific BTF transformations in tree, which will reduce kbuild
dependency on pahole's features.
resolve_btfids currently identifies kfuncs by reading the "bpf_kfunc"
decl tags pahole emits into vmlinux BTF. The series switches the
source of truth to the BTF ID sets registered with
BTF_KFUNCS_START()/END() in the kernel, which is the mechanism BPF
verifier uses.
The series is based on patches #5 and #6 from the original
"resolve_btfids: Implement BTF tags emission for kfuncs" series [1],
and includes a few significant additions. Particularly the build time
enforcement of kfunc flags consistency [2].
The series consists of:
- patches #1-#3 implement supporting infrastructure for the proper
kfunc discovery and deduplication
- patches #4-#5 expose btf__find_by_name_kind_own() and use it to
fix a latent bug in _impl func lookup
- patch #6 fixes inconsistent kfunc flags for HID kfuncs
- patch #7 implements kfunc discovery from BTF ID sets
- patch #8 adds enforcement of kfunc flags consistency
The resolve_btfids selftests patches have landed earlier [3].
[1] https://lore.kernel.org/bpf/20260601221805.821394-1-ihor.solodrai@linux.dev/
[2] https://lore.kernel.org/bpf/9b2196dd-443b-4632-ae11-030cdbdc59b4@linux.dev/
[3] https://lore.kernel.org/bpf/20260617210619.1562858-1-ihor.solodrai@linux.dev/
---
Changes compared to [1]:
- Drop the idempotency (ensure_*) machinery: assume valid input BTF (Andrii)
- Use rbtree to store the kfuncs (Andrii)
- Enforce full KF_* flag consistency as a build error (Eduard)
- Various cleanups and nits (Andrii, Emil, Jiri)
---
Ihor Solodrai (8):
resolve_btfids: Implement generic ensure_mem() to grow arrays
resolve_btfids: Index BTF ID symbols by address
resolve_btfids: Keep collected kfuncs in a rbtree
libbpf: Export btf__find_by_name_kind_own()
resolve_btfids: Fix the _impl lookup for module BTF
HID: bpf: Make syscall kfunc flags match the struct_ops set
resolve_btfids: Discover kfuncs from BTF ID sets
resolve_btfids: Enforce consistent kfunc flags across BTF ID sets
drivers/hid/bpf/hid_bpf_dispatch.c | 10 +-
tools/bpf/resolve_btfids/main.c | 275 ++++++++++++++++++-----------
tools/lib/bpf/btf.h | 2 +
tools/lib/bpf/libbpf.map | 1 +
tools/lib/bpf/libbpf_internal.h | 2 -
5 files changed, 181 insertions(+), 109 deletions(-)
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH bpf-next v1 1/8] resolve_btfids: Implement generic ensure_mem() to grow arrays
2026-07-22 23:35 [PATCH bpf-next v1 0/8] resolve_btfids: Discover kfuncs from BTF ID sets Ihor Solodrai
@ 2026-07-22 23:35 ` Ihor Solodrai
2026-07-22 23:48 ` sashiko-bot
2026-07-22 23:35 ` [PATCH bpf-next v1 2/8] resolve_btfids: Index BTF ID symbols by address Ihor Solodrai
` (6 subsequent siblings)
7 siblings, 1 reply; 21+ messages in thread
From: Ihor Solodrai @ 2026-07-22 23:35 UTC (permalink / raw)
To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Kumar Kartikeya Dwivedi
Cc: Benjamin Tissoires, Jiri Kosina, Emil Tsalapatis, Jiri Olsa, bpf,
linux-input, kernel-team
push_*() helpers in resolve_btfids contain copy-pasted array growth
logic. Factor it out into ensure_mem() - a simplified variant of
libbpf_ensure_mem(), and use it in the helpers.
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
tools/bpf/resolve_btfids/main.c | 55 ++++++++++++++++++++-------------
1 file changed, 33 insertions(+), 22 deletions(-)
diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
index f8a91fa7584f..183466ddc5f9 100644
--- a/tools/bpf/resolve_btfids/main.c
+++ b/tools/bpf/resolve_btfids/main.c
@@ -201,6 +201,35 @@ static int eprintf(int level, int var, const char *fmt, ...)
#define pr_info(fmt, ...) \
eprintf(0, verbose, pr_fmt(fmt), ##__VA_ARGS__)
+/*
+ * Grow *data so it can hold at least cnt elements of elem_sz bytes each.
+ * *cap is the capacity in elements and is updated on growth.
+ */
+static int __ensure_mem(void **data, u32 *cap, u32 cnt, size_t elem_sz)
+{
+ u32 new_cap, old_cap = *cap;
+ void *arr;
+
+ if (cnt <= old_cap)
+ return 0;
+
+ new_cap = max(old_cap + 256, old_cap * 2);
+ if (new_cap < cnt)
+ new_cap = cnt;
+
+ arr = realloc(*data, elem_sz * new_cap);
+ if (!arr)
+ return -ENOMEM;
+
+ *data = arr;
+ *cap = new_cap;
+
+ return 0;
+}
+
+#define ensure_mem(arr_ptr, cap_ptr, cnt) \
+ __ensure_mem((void **)(arr_ptr), (cap_ptr), (cnt), sizeof(**(arr_ptr)))
+
static bool is_btf_id(const char *name)
{
return name && !strncmp(name, BTF_ID_PREFIX, sizeof(BTF_ID_PREFIX) - 1);
@@ -890,17 +919,8 @@ static const struct btf_type *btf_type_skip_qualifiers(const struct btf *btf, s3
static int push_decl_tag_id(struct btf2btf_context *ctx, u32 decl_tag_id)
{
- u32 *arr = ctx->decl_tags;
- u32 cap = ctx->max_decl_tags;
-
- if (ctx->nr_decl_tags + 1 > cap) {
- cap = max(cap + 256, cap * 2);
- arr = realloc(arr, sizeof(u32) * cap);
- if (!arr)
- return -ENOMEM;
- ctx->max_decl_tags = cap;
- ctx->decl_tags = arr;
- }
+ if (ensure_mem(&ctx->decl_tags, &ctx->max_decl_tags, ctx->nr_decl_tags + 1))
+ return -ENOMEM;
ctx->decl_tags[ctx->nr_decl_tags++] = decl_tag_id;
@@ -909,17 +929,8 @@ static int push_decl_tag_id(struct btf2btf_context *ctx, u32 decl_tag_id)
static int push_kfunc(struct btf2btf_context *ctx, struct kfunc *kfunc)
{
- struct kfunc *arr = ctx->kfuncs;
- u32 cap = ctx->max_kfuncs;
-
- if (ctx->nr_kfuncs + 1 > cap) {
- cap = max(cap + 256, cap * 2);
- arr = realloc(arr, sizeof(struct kfunc) * cap);
- if (!arr)
- return -ENOMEM;
- ctx->max_kfuncs = cap;
- ctx->kfuncs = arr;
- }
+ if (ensure_mem(&ctx->kfuncs, &ctx->max_kfuncs, ctx->nr_kfuncs + 1))
+ return -ENOMEM;
ctx->kfuncs[ctx->nr_kfuncs++] = *kfunc;
--
2.55.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH bpf-next v1 2/8] resolve_btfids: Index BTF ID symbols by address
2026-07-22 23:35 [PATCH bpf-next v1 0/8] resolve_btfids: Discover kfuncs from BTF ID sets Ihor Solodrai
2026-07-22 23:35 ` [PATCH bpf-next v1 1/8] resolve_btfids: Implement generic ensure_mem() to grow arrays Ihor Solodrai
@ 2026-07-22 23:35 ` Ihor Solodrai
2026-07-22 23:35 ` [PATCH bpf-next v1 3/8] resolve_btfids: Keep collected kfuncs in a rbtree Ihor Solodrai
` (5 subsequent siblings)
7 siblings, 0 replies; 21+ messages in thread
From: Ihor Solodrai @ 2026-07-22 23:35 UTC (permalink / raw)
To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Kumar Kartikeya Dwivedi
Cc: Benjamin Tissoires, Jiri Kosina, Emil Tsalapatis, Jiri Olsa, bpf,
linux-input, kernel-team
Keep an address-sorted index of parsed .BTF_ids symbols so that the
original BTF_ID symbol name can be recovered from an entry address.
Use the index in find_kfunc_flags() to scan BTF_SET8_KFUNCS entries
directly and match each entry back to the requested kfunc.
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
---
tools/bpf/resolve_btfids/main.c | 96 ++++++++++++++++++++++++---------
1 file changed, 72 insertions(+), 24 deletions(-)
diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
index 183466ddc5f9..3198198b03a7 100644
--- a/tools/bpf/resolve_btfids/main.c
+++ b/tools/bpf/resolve_btfids/main.c
@@ -119,6 +119,11 @@ struct btf_id {
Elf64_Addr addr[ADDR_CNT];
};
+struct addr_sym {
+ Elf64_Addr addr;
+ const char *name;
+};
+
struct object {
const char *path;
const char *btf_path;
@@ -150,6 +155,10 @@ struct object {
int nr_structs;
int nr_unions;
int nr_typedefs;
+
+ struct addr_sym *addr_syms;
+ u32 addr_syms_cnt;
+ u32 addr_syms_cap;
};
#define KF_IMPLICIT_ARGS (1 << 16)
@@ -509,6 +518,40 @@ static int elf_collect(struct object *obj)
return 0;
}
+static int push_addr_sym(struct object *obj, Elf64_Addr addr, const char *name)
+{
+ if (ensure_mem(&obj->addr_syms, &obj->addr_syms_cap, obj->addr_syms_cnt + 1))
+ return -ENOMEM;
+
+ obj->addr_syms[obj->addr_syms_cnt++] = (struct addr_sym){
+ .addr = addr,
+ .name = name,
+ };
+
+ return 0;
+}
+
+static int cmp_addr_sym(const void *a, const void *b)
+{
+ Elf64_Addr aa = ((const struct addr_sym *)a)->addr;
+ Elf64_Addr ab = ((const struct addr_sym *)b)->addr;
+
+ return (aa > ab) - (aa < ab);
+}
+
+static const char *find_name_by_addr(struct object *obj, Elf64_Addr addr)
+{
+ struct addr_sym key = { .addr = addr };
+ struct addr_sym *res;
+
+ if (!obj->addr_syms_cnt)
+ return NULL;
+
+ res = bsearch(&key, obj->addr_syms, obj->addr_syms_cnt,
+ sizeof(*obj->addr_syms), cmp_addr_sym);
+ return res ? res->name : NULL;
+}
+
static int symbols_collect(struct object *obj)
{
Elf_Scn *scn = NULL;
@@ -602,8 +645,15 @@ static int symbols_collect(struct object *obj)
return -1;
}
id->addr[id->addr_cnt++] = sym.st_value;
+
+ if (push_addr_sym(obj, sym.st_value, id->name))
+ return -1;
}
+ if (obj->addr_syms_cnt)
+ qsort(obj->addr_syms, obj->addr_syms_cnt,
+ sizeof(*obj->addr_syms), cmp_addr_sym);
+
return 0;
}
@@ -957,43 +1007,40 @@ static int collect_decl_tags(struct btf2btf_context *ctx)
}
/*
- * To find the kfunc flags having its struct btf_id (with ELF addresses)
- * we need to find the address that is in range of a set8.
- * If a set8 is found, then the flags are located at addr + 4 bytes.
+ * To find kfunc flags, scan BTF_SET8_KFUNCS entries and use the entry
+ * address to recover the corresponding BTF_ID symbol name.
* Return 0 (no flags!) if not found.
*/
static u32 find_kfunc_flags(struct object *obj, struct btf_id *kfunc_id)
{
- const u32 *elf_data_ptr = obj->efile.idlist->d_buf;
- u64 set_lower_addr, set_upper_addr, addr;
+ Elf_Data *idlist = obj->efile.idlist;
struct btf_id *set_id;
struct rb_node *next;
- u32 flags;
- u64 idx;
for (next = rb_first(&obj->sets); next; next = rb_next(next)) {
+ struct btf_id_set8 *set8;
+ u64 set_addr;
+
set_id = rb_entry(next, struct btf_id, rb_node);
if (set_id->kind != BTF_ID_KIND_SET8 || set_id->addr_cnt != 1)
continue;
- set_lower_addr = set_id->addr[0];
- set_upper_addr = set_lower_addr + set_id->cnt * sizeof(u64);
+ set_addr = set_id->addr[0];
+ set8 = idlist->d_buf + (set_addr - obj->efile.idlist_addr);
+ if (!(set8->flags & BTF_SET8_KFUNCS))
+ continue;
- for (u32 i = 0; i < kfunc_id->addr_cnt; i++) {
- addr = kfunc_id->addr[i];
- /*
- * Lower bound is exclusive to skip the 8-byte header of the set.
- * Upper bound is inclusive to capture the last entry at offset 8*cnt.
- */
- if (set_lower_addr < addr && addr <= set_upper_addr) {
- pr_debug("found kfunc %s in BTF_ID_FLAGS %s\n",
- kfunc_id->name, set_id->name);
- idx = addr - obj->efile.idlist_addr;
- idx = idx / sizeof(u32) + 1;
- flags = elf_data_ptr[idx];
-
- return flags;
- }
+ for (u32 i = 0; i < set_id->cnt; i++) {
+ size_t off = (char *)&set8->pairs[i] - (char *)set8;
+ const char *name = find_name_by_addr(obj, set_addr + off);
+
+ if (!name || strcmp(name, kfunc_id->name) != 0)
+ continue;
+
+ pr_debug("found kfunc %s in BTF_ID_FLAGS %s\n",
+ kfunc_id->name, set_id->name);
+
+ return set8->pairs[i].flags;
}
}
@@ -1586,6 +1633,7 @@ int main(int argc, const char **argv)
btf_id__free_all(&obj.typedefs);
btf_id__free_all(&obj.funcs);
btf_id__free_all(&obj.sets);
+ free(obj.addr_syms);
if (obj.efile.elf) {
elf_end(obj.efile.elf);
close(obj.efile.fd);
--
2.55.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH bpf-next v1 3/8] resolve_btfids: Keep collected kfuncs in a rbtree
2026-07-22 23:35 [PATCH bpf-next v1 0/8] resolve_btfids: Discover kfuncs from BTF ID sets Ihor Solodrai
2026-07-22 23:35 ` [PATCH bpf-next v1 1/8] resolve_btfids: Implement generic ensure_mem() to grow arrays Ihor Solodrai
2026-07-22 23:35 ` [PATCH bpf-next v1 2/8] resolve_btfids: Index BTF ID symbols by address Ihor Solodrai
@ 2026-07-22 23:35 ` Ihor Solodrai
2026-07-22 23:50 ` sashiko-bot
2026-07-22 23:35 ` [PATCH bpf-next v1 4/8] libbpf: Export btf__find_by_name_kind_own() Ihor Solodrai
` (4 subsequent siblings)
7 siblings, 1 reply; 21+ messages in thread
From: Ihor Solodrai @ 2026-07-22 23:35 UTC (permalink / raw)
To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Kumar Kartikeya Dwivedi
Cc: Benjamin Tissoires, Jiri Kosina, Emil Tsalapatis, Jiri Olsa, bpf,
linux-input, kernel-team
Store collected kfuncs in a rbtree keyed by BTF ID instead of a
dynamically grown array. This allows for efficient deduplication for
kfuncs declared in multiple sets, which is needed for subsequent
patches [1].
[1] https://lore.kernel.org/bpf/CAEf4BzaLzX3mXvQzxv+gbmZOh84XvYofLjMSWFYghNjS-ohEZg@mail.gmail.com/
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
tools/bpf/resolve_btfids/main.c | 50 +++++++++++++++++++++++++++------
1 file changed, 42 insertions(+), 8 deletions(-)
diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
index 3198198b03a7..de4986e1bc3d 100644
--- a/tools/bpf/resolve_btfids/main.c
+++ b/tools/bpf/resolve_btfids/main.c
@@ -165,6 +165,7 @@ struct object {
#define KF_IMPL_SUFFIX "_impl"
struct kfunc {
+ struct rb_node rb_node;
const char *name;
u32 btf_id;
u32 flags;
@@ -175,9 +176,7 @@ struct btf2btf_context {
u32 *decl_tags;
u32 nr_decl_tags;
u32 max_decl_tags;
- struct kfunc *kfuncs;
- u32 nr_kfuncs;
- u32 max_kfuncs;
+ struct rb_root kfuncs;
};
static int verbose;
@@ -979,14 +978,48 @@ static int push_decl_tag_id(struct btf2btf_context *ctx, u32 decl_tag_id)
static int push_kfunc(struct btf2btf_context *ctx, struct kfunc *kfunc)
{
- if (ensure_mem(&ctx->kfuncs, &ctx->max_kfuncs, ctx->nr_kfuncs + 1))
+ struct rb_node **p = &ctx->kfuncs.rb_node;
+ struct rb_node *parent = NULL;
+ struct kfunc *k;
+
+ /* Dedup by BTF ID: collecting the same kfunc twice is a no-op. */
+ while (*p) {
+ parent = *p;
+ k = rb_entry(parent, struct kfunc, rb_node);
+
+ if (kfunc->btf_id < k->btf_id)
+ p = &(*p)->rb_left;
+ else if (kfunc->btf_id > k->btf_id)
+ p = &(*p)->rb_right;
+ else
+ return 0;
+ }
+
+ k = zalloc(sizeof(*k));
+ if (!k)
return -ENOMEM;
- ctx->kfuncs[ctx->nr_kfuncs++] = *kfunc;
+ *k = *kfunc;
+ rb_link_node(&k->rb_node, parent, p);
+ rb_insert_color(&k->rb_node, &ctx->kfuncs);
return 0;
}
+static void free_kfuncs(struct rb_root *root)
+{
+ struct rb_node *next;
+ struct kfunc *kfunc;
+
+ next = rb_first(root);
+ while (next) {
+ kfunc = rb_entry(next, struct kfunc, rb_node);
+ next = rb_next(&kfunc->rb_node);
+ rb_erase(&kfunc->rb_node, root);
+ free(kfunc);
+ }
+}
+
static int collect_decl_tags(struct btf2btf_context *ctx)
{
const u32 type_cnt = btf__type_cnt(ctx->btf);
@@ -1272,14 +1305,15 @@ static int process_kfunc_with_implicit_args(struct btf2btf_context *ctx, struct
static int btf2btf(struct object *obj)
{
struct btf2btf_context ctx = {};
+ struct rb_node *next;
int err;
err = build_btf2btf_context(obj, &ctx);
if (err)
goto out;
- for (u32 i = 0; i < ctx.nr_kfuncs; i++) {
- struct kfunc *kfunc = &ctx.kfuncs[i];
+ for (next = rb_first(&ctx.kfuncs); next; next = rb_next(next)) {
+ struct kfunc *kfunc = rb_entry(next, struct kfunc, rb_node);
if (!(kfunc->flags & KF_IMPLICIT_ARGS))
continue;
@@ -1292,7 +1326,7 @@ static int btf2btf(struct object *obj)
err = 0;
out:
free(ctx.decl_tags);
- free(ctx.kfuncs);
+ free_kfuncs(&ctx.kfuncs);
return err;
}
--
2.55.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH bpf-next v1 4/8] libbpf: Export btf__find_by_name_kind_own()
2026-07-22 23:35 [PATCH bpf-next v1 0/8] resolve_btfids: Discover kfuncs from BTF ID sets Ihor Solodrai
` (2 preceding siblings ...)
2026-07-22 23:35 ` [PATCH bpf-next v1 3/8] resolve_btfids: Keep collected kfuncs in a rbtree Ihor Solodrai
@ 2026-07-22 23:35 ` Ihor Solodrai
2026-07-22 23:43 ` sashiko-bot
2026-07-22 23:35 ` [PATCH bpf-next v1 5/8] resolve_btfids: Fix the _impl lookup for module BTF Ihor Solodrai
` (3 subsequent siblings)
7 siblings, 1 reply; 21+ messages in thread
From: Ihor Solodrai @ 2026-07-22 23:35 UTC (permalink / raw)
To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Kumar Kartikeya Dwivedi
Cc: Benjamin Tissoires, Jiri Kosina, Emil Tsalapatis, Jiri Olsa, bpf,
linux-input, kernel-team
btf__find_by_name_kind() searches the base BTF before the split BTF,
so in case of a name collision between base and split it always
returns a base type. Tools that process split BTF may need to restrict
a lookup to the split's own types.
The internal helper btf__find_by_name_kind_own() already does exactly
that. Make it a public API.
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
tools/lib/bpf/btf.h | 2 ++
tools/lib/bpf/libbpf.map | 1 +
tools/lib/bpf/libbpf_internal.h | 2 --
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
index 1a31f2da947f..587172c0de08 100644
--- a/tools/lib/bpf/btf.h
+++ b/tools/lib/bpf/btf.h
@@ -172,6 +172,8 @@ LIBBPF_API __s32 btf__find_by_name(const struct btf *btf,
const char *type_name);
LIBBPF_API __s32 btf__find_by_name_kind(const struct btf *btf,
const char *type_name, __u32 kind);
+LIBBPF_API __s32 btf__find_by_name_kind_own(const struct btf *btf,
+ const char *type_name, __u32 kind);
LIBBPF_API __u32 btf__type_cnt(const struct btf *btf);
LIBBPF_API const struct btf *btf__base_btf(const struct btf *btf);
LIBBPF_API const struct btf_type *btf__type_by_id(const struct btf *btf,
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index b731df19ae69..08ab2ea881fb 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -460,5 +460,6 @@ LIBBPF_1.8.0 {
global:
bpf_program__attach_tracing_multi;
bpf_program__clone;
+ btf__find_by_name_kind_own;
btf__new_empty_opts;
} LIBBPF_1.7.0;
diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h
index d5b7db703b3f..7a74abb904f8 100644
--- a/tools/lib/bpf/libbpf_internal.h
+++ b/tools/lib/bpf/libbpf_internal.h
@@ -596,8 +596,6 @@ typedef int (*type_id_visit_fn)(__u32 *type_id, void *ctx);
typedef int (*str_off_visit_fn)(__u32 *str_off, void *ctx);
int btf_ext_visit_type_ids(struct btf_ext *btf_ext, type_id_visit_fn visit, void *ctx);
int btf_ext_visit_str_offs(struct btf_ext *btf_ext, str_off_visit_fn visit, void *ctx);
-__s32 btf__find_by_name_kind_own(const struct btf *btf, const char *type_name,
- __u32 kind);
/* handle direct returned errors */
static inline int libbpf_err(int ret)
--
2.55.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH bpf-next v1 5/8] resolve_btfids: Fix the _impl lookup for module BTF
2026-07-22 23:35 [PATCH bpf-next v1 0/8] resolve_btfids: Discover kfuncs from BTF ID sets Ihor Solodrai
` (3 preceding siblings ...)
2026-07-22 23:35 ` [PATCH bpf-next v1 4/8] libbpf: Export btf__find_by_name_kind_own() Ihor Solodrai
@ 2026-07-22 23:35 ` Ihor Solodrai
2026-07-23 0:46 ` bot+bpf-ci
2026-07-22 23:35 ` [PATCH bpf-next v1 6/8] HID: bpf: Make syscall kfunc flags match the struct_ops set Ihor Solodrai
` (2 subsequent siblings)
7 siblings, 1 reply; 21+ messages in thread
From: Ihor Solodrai @ 2026-07-22 23:35 UTC (permalink / raw)
To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Kumar Kartikeya Dwivedi
Cc: Benjamin Tissoires, Jiri Kosina, Emil Tsalapatis, Jiri Olsa, bpf,
linux-input, kernel-team
process_kfunc_with_implicit_args() skips generating <name>_impl
function when one already exists for backwards compatibility.
It uses btf__find_by_name_kind(), which searches the base BTF before
the split BTF. When resolve_btfids processes a module, a same-named
_impl in vmlinux would be found and the module's own counterpart would
not be created.
Fix by using btf__find_by_name_kind_own() for the lookup.
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
tools/bpf/resolve_btfids/main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
index de4986e1bc3d..ab3ab3045592 100644
--- a/tools/bpf/resolve_btfids/main.c
+++ b/tools/bpf/resolve_btfids/main.c
@@ -1232,7 +1232,7 @@ static int process_kfunc_with_implicit_args(struct btf2btf_context *ctx, struct
return -E2BIG;
}
- if (btf__find_by_name_kind(btf, tmp_name, BTF_KIND_FUNC) > 0) {
+ if (btf__find_by_name_kind_own(btf, tmp_name, BTF_KIND_FUNC) > 0) {
pr_debug("resolve_btfids: function %s already exists in BTF\n", tmp_name);
goto add_new_proto;
}
--
2.55.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH bpf-next v1 6/8] HID: bpf: Make syscall kfunc flags match the struct_ops set
2026-07-22 23:35 [PATCH bpf-next v1 0/8] resolve_btfids: Discover kfuncs from BTF ID sets Ihor Solodrai
` (4 preceding siblings ...)
2026-07-22 23:35 ` [PATCH bpf-next v1 5/8] resolve_btfids: Fix the _impl lookup for module BTF Ihor Solodrai
@ 2026-07-22 23:35 ` Ihor Solodrai
2026-07-22 23:49 ` sashiko-bot
2026-07-22 23:35 ` [PATCH bpf-next v1 7/8] resolve_btfids: Discover kfuncs from BTF ID sets Ihor Solodrai
2026-07-22 23:35 ` [PATCH bpf-next v1 8/8] resolve_btfids: Enforce consistent kfunc flags across " Ihor Solodrai
7 siblings, 1 reply; 21+ messages in thread
From: Ihor Solodrai @ 2026-07-22 23:35 UTC (permalink / raw)
To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Kumar Kartikeya Dwivedi
Cc: Benjamin Tissoires, Jiri Kosina, Emil Tsalapatis, Jiri Olsa, bpf,
linux-input, kernel-team
Update kfunc flags for hid_bpf_syscall_kfunc_ids set to exactly match
hid_bpf_kfunc_ids set by adding KF_SLEEPABLE flag.
The syscall set omitted the flag because syscall programs are always
sleepable (the verifier rejects a non-sleepable syscall program).
However the upcoming resolve_btfids change enforces per-kfunc flag
consistency across BTF ID sets at build time, which is why this change
is necessary.
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
drivers/hid/bpf/hid_bpf_dispatch.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c
index 536f6d01fd14..44671dbdeca8 100644
--- a/drivers/hid/bpf/hid_bpf_dispatch.c
+++ b/drivers/hid/bpf/hid_bpf_dispatch.c
@@ -590,11 +590,11 @@ static const struct btf_kfunc_id_set hid_bpf_kfunc_set = {
/* for syscall HID-BPF */
BTF_KFUNCS_START(hid_bpf_syscall_kfunc_ids)
-BTF_ID_FLAGS(func, hid_bpf_allocate_context, KF_ACQUIRE | KF_RET_NULL)
-BTF_ID_FLAGS(func, hid_bpf_release_context, KF_RELEASE)
-BTF_ID_FLAGS(func, hid_bpf_hw_request)
-BTF_ID_FLAGS(func, hid_bpf_hw_output_report)
-BTF_ID_FLAGS(func, hid_bpf_input_report)
+BTF_ID_FLAGS(func, hid_bpf_allocate_context, KF_ACQUIRE | KF_RET_NULL | KF_SLEEPABLE)
+BTF_ID_FLAGS(func, hid_bpf_release_context, KF_RELEASE | KF_SLEEPABLE)
+BTF_ID_FLAGS(func, hid_bpf_hw_request, KF_SLEEPABLE)
+BTF_ID_FLAGS(func, hid_bpf_hw_output_report, KF_SLEEPABLE)
+BTF_ID_FLAGS(func, hid_bpf_input_report, KF_SLEEPABLE)
BTF_KFUNCS_END(hid_bpf_syscall_kfunc_ids)
static const struct btf_kfunc_id_set hid_bpf_syscall_kfunc_set = {
--
2.55.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH bpf-next v1 7/8] resolve_btfids: Discover kfuncs from BTF ID sets
2026-07-22 23:35 [PATCH bpf-next v1 0/8] resolve_btfids: Discover kfuncs from BTF ID sets Ihor Solodrai
` (5 preceding siblings ...)
2026-07-22 23:35 ` [PATCH bpf-next v1 6/8] HID: bpf: Make syscall kfunc flags match the struct_ops set Ihor Solodrai
@ 2026-07-22 23:35 ` Ihor Solodrai
2026-07-23 0:32 ` bot+bpf-ci
2026-07-22 23:35 ` [PATCH bpf-next v1 8/8] resolve_btfids: Enforce consistent kfunc flags across " Ihor Solodrai
7 siblings, 1 reply; 21+ messages in thread
From: Ihor Solodrai @ 2026-07-22 23:35 UTC (permalink / raw)
To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Kumar Kartikeya Dwivedi
Cc: Benjamin Tissoires, Jiri Kosina, Emil Tsalapatis, Jiri Olsa, bpf,
linux-input, kernel-team
collect_kfuncs() currently uses bpf_kfunc decl tags to identify the
list of kfuncs. The decl tags are generated by pahole, which makes
current implementation implicitly rely on those tags being generated.
The authoritative source, used by the the BPF verifier for kfunc
registration, of functions being BPF kfuncs are
BTF_KFUNCS_START()/END() declarations. These are BTF_ID_SET8 under the
hood. Currently resolve_btfids reads kfunc flags from these sets, and
populates them with BTF IDs.
Implement kfunc discovery from BTF_ID_SET8 symbols in resolve_btfids,
removing the dependency on pahole's emmission of decl tags.
Walk BTF_ID_KIND_SET8 sets, and use the address-to-symbol index to
look up set entry's BTF_ID symbol name (before .BTF_ids is patched),
recording the paired flags directly. This makes find_kfunc_flags()
helper unnecessary, so it's removed.
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
tools/bpf/resolve_btfids/main.c | 89 +++++++++++----------------------
1 file changed, 29 insertions(+), 60 deletions(-)
diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
index ab3ab3045592..338d0c0a8e58 100644
--- a/tools/bpf/resolve_btfids/main.c
+++ b/tools/bpf/resolve_btfids/main.c
@@ -1039,19 +1039,18 @@ static int collect_decl_tags(struct btf2btf_context *ctx)
return 0;
}
-/*
- * To find kfunc flags, scan BTF_SET8_KFUNCS entries and use the entry
- * address to recover the corresponding BTF_ID symbol name.
- * Return 0 (no flags!) if not found.
- */
-static u32 find_kfunc_flags(struct object *obj, struct btf_id *kfunc_id)
+static int collect_kfuncs(struct object *obj, struct btf2btf_context *ctx)
{
Elf_Data *idlist = obj->efile.idlist;
- struct btf_id *set_id;
+ struct btf *btf = ctx->btf;
struct rb_node *next;
+ if (!idlist || !idlist->d_buf)
+ return 0;
+
for (next = rb_first(&obj->sets); next; next = rb_next(next)) {
struct btf_id_set8 *set8;
+ struct btf_id *set_id;
u64 set_addr;
set_id = rb_entry(next, struct btf_id, rb_node);
@@ -1066,64 +1065,34 @@ static u32 find_kfunc_flags(struct object *obj, struct btf_id *kfunc_id)
for (u32 i = 0; i < set_id->cnt; i++) {
size_t off = (char *)&set8->pairs[i] - (char *)set8;
const char *name = find_name_by_addr(obj, set_addr + off);
+ struct kfunc kfunc;
+ s32 func_id;
+ int err;
- if (!name || strcmp(name, kfunc_id->name) != 0)
+ if (!name) {
+ pr_err("WARN: resolve_btfids: no BTF ID symbol for %s entry %u\n",
+ set_id->name, i);
+ warnings++;
continue;
+ }
- pr_debug("found kfunc %s in BTF_ID_FLAGS %s\n",
- kfunc_id->name, set_id->name);
-
- return set8->pairs[i].flags;
- }
- }
-
- return 0;
-}
-
-static int collect_kfuncs(struct object *obj, struct btf2btf_context *ctx)
-{
- const char *tag_name, *func_name;
- struct btf *btf = ctx->btf;
- const struct btf_type *t;
- u32 flags, func_id;
- struct kfunc kfunc;
- struct btf_id *id;
- int err;
-
- if (ctx->nr_decl_tags == 0)
- return 0;
-
- for (u32 i = 0; i < ctx->nr_decl_tags; i++) {
- t = btf__type_by_id(btf, ctx->decl_tags[i]);
- if (btf_kflag(t) || btf_decl_tag(t)->component_idx != -1)
- continue;
-
- tag_name = btf__name_by_offset(btf, t->name_off);
- if (strcmp(tag_name, "bpf_kfunc") != 0)
- continue;
-
- func_id = t->type;
- t = btf__type_by_id(btf, func_id);
- if (!btf_is_func(t))
- continue;
-
- func_name = btf__name_by_offset(btf, t->name_off);
- if (!func_name)
- continue;
-
- id = btf_id__find(&obj->funcs, func_name);
- if (!id || id->kind != BTF_ID_KIND_SYM)
- continue;
-
- flags = find_kfunc_flags(obj, id);
+ func_id = btf__find_by_name_kind_own(btf, name, BTF_KIND_FUNC);
+ if (func_id < 0) {
+ pr_err("WARN: resolve_btfids: no BTF func for kfunc %s in %s\n",
+ name, set_id->name);
+ warnings++;
+ continue;
+ }
- kfunc.name = id->name;
- kfunc.btf_id = func_id;
- kfunc.flags = flags;
+ pr_debug("found kfunc %s in %s\n", name, set_id->name);
- err = push_kfunc(ctx, &kfunc);
- if (err)
- return err;
+ kfunc.name = name;
+ kfunc.btf_id = func_id;
+ kfunc.flags = set8->pairs[i].flags;
+ err = push_kfunc(ctx, &kfunc);
+ if (err)
+ return err;
+ }
}
return 0;
--
2.55.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH bpf-next v1 8/8] resolve_btfids: Enforce consistent kfunc flags across BTF ID sets
2026-07-22 23:35 [PATCH bpf-next v1 0/8] resolve_btfids: Discover kfuncs from BTF ID sets Ihor Solodrai
` (6 preceding siblings ...)
2026-07-22 23:35 ` [PATCH bpf-next v1 7/8] resolve_btfids: Discover kfuncs from BTF ID sets Ihor Solodrai
@ 2026-07-22 23:35 ` Ihor Solodrai
2026-07-23 0:32 ` bot+bpf-ci
7 siblings, 1 reply; 21+ messages in thread
From: Ihor Solodrai @ 2026-07-22 23:35 UTC (permalink / raw)
To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
Eduard Zingerman, Kumar Kartikeya Dwivedi
Cc: Benjamin Tissoires, Jiri Kosina, Emil Tsalapatis, Jiri Olsa, bpf,
linux-input, kernel-team
A kfunc may be listed in several BTF ID sets, which is expected
because different kfuncs are available to BPF programs depending on
their type.
However kfunc flags across different BTF ID sets must be consistent [1].
The flags should be considered a part of the kfunc declaration,
because they influence its BTF representation and verifier handling.
Enforce the kfunc flag consistency in resolve_btifds by hard failing
on error and blocking kernel (or module) build.
[1] https://lore.kernel.org/bpf/9b2196dd-443b-4632-ae11-030cdbdc59b4@linux.dev/
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
tools/bpf/resolve_btfids/main.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
index 338d0c0a8e58..85488935909d 100644
--- a/tools/bpf/resolve_btfids/main.c
+++ b/tools/bpf/resolve_btfids/main.c
@@ -982,17 +982,26 @@ static int push_kfunc(struct btf2btf_context *ctx, struct kfunc *kfunc)
struct rb_node *parent = NULL;
struct kfunc *k;
- /* Dedup by BTF ID: collecting the same kfunc twice is a no-op. */
+ /*
+ * Dedup by BTF ID: collecting the same kfunc twice is a no-op,
+ * UNLESS the kfunc flags are inconsistent, in which case we
+ * fail hard because it indicates a bug in a kfunc set declaration.
+ */
while (*p) {
parent = *p;
k = rb_entry(parent, struct kfunc, rb_node);
- if (kfunc->btf_id < k->btf_id)
+ if (kfunc->btf_id < k->btf_id) {
p = &(*p)->rb_left;
- else if (kfunc->btf_id > k->btf_id)
+ } else if (kfunc->btf_id > k->btf_id) {
p = &(*p)->rb_right;
- else
+ } else if (k->flags == kfunc->flags) {
return 0;
+ } else {
+ pr_err("ERROR: resolve_btfids: kfunc %s has inconsistent flags across BTF ID sets: 0x%x != 0x%x\n",
+ kfunc->name, k->flags, kfunc->flags);
+ return -EINVAL;
+ }
}
k = zalloc(sizeof(*k));
--
2.55.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH bpf-next v1 4/8] libbpf: Export btf__find_by_name_kind_own()
2026-07-22 23:35 ` [PATCH bpf-next v1 4/8] libbpf: Export btf__find_by_name_kind_own() Ihor Solodrai
@ 2026-07-22 23:43 ` sashiko-bot
2026-07-23 0:45 ` Ihor Solodrai
0 siblings, 1 reply; 21+ messages in thread
From: sashiko-bot @ 2026-07-22 23:43 UTC (permalink / raw)
To: Ihor Solodrai; +Cc: linux-input, bpf, dmitry.torokhov
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The newly exposed public libbpf API `btf__find_by_name_kind_own()` lacks the `libbpf_err()` wrapper on its error return path.
--
--- Patch [4]: [PATCH bpf-next v1 4/8] libbpf: Export btf__find_by_name_kind_own() ---
commit 60b04eac1753190ac945126aaca0759082942bc0
Author: Ihor Solodrai <ihor.solodrai@linux.dev>
libbpf: Export btf__find_by_name_kind_own()
btf__find_by_name_kind() searches the base BTF before the split BTF,
so in case of a name collision between base and split it always
returns a base type. Tools that process split BTF may need to restrict
a lookup to the split's own types.
The internal helper btf__find_by_name_kind_own() already does exactly
that. Make it a public API.
> diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
> index 1a31f2da947f8..587172c0de089 100644
> --- a/tools/lib/bpf/btf.h
> +++ b/tools/lib/bpf/btf.h
> @@ -172,6 +172,8 @@ LIBBPF_API __s32 btf__find_by_name(const struct btf *btf,
> const char *type_name);
> LIBBPF_API __s32 btf__find_by_name_kind(const struct btf *btf,
> const char *type_name, __u32 kind);
> +LIBBPF_API __s32 btf__find_by_name_kind_own(const struct btf *btf,
> + const char *type_name, __u32 kind);
[Severity: Medium]
Since btf__find_by_name_kind_own() is now a public API, shouldn't its return
path in tools/lib/bpf/btf.c be updated to use libbpf_err()?
Currently, it returns the value from the internal helper directly:
tools/lib/bpf/btf.c:btf__find_by_name_kind_own() {
return btf_find_by_name_kind(btf, btf->start_id, type_name, kind);
}
The libbpf public API error handling contract requires all public API functions
to set errno using libbpf_err() directly on their return statements. While the
internal helper btf_find_by_name_kind() currently sets errno indirectly, relying
on it could cause issues if the internal helper is later fixed to return raw
error codes.
Should this be updated to return libbpf_err(btf_find_by_name_kind(...))?
> LIBBPF_API __u32 btf__type_cnt(const struct btf *btf);
> LIBBPF_API const struct btf *btf__base_btf(const struct btf *btf);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260722233518.778854-1-ihor.solodrai@linux.dev?part=4
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH bpf-next v1 1/8] resolve_btfids: Implement generic ensure_mem() to grow arrays
2026-07-22 23:35 ` [PATCH bpf-next v1 1/8] resolve_btfids: Implement generic ensure_mem() to grow arrays Ihor Solodrai
@ 2026-07-22 23:48 ` sashiko-bot
2026-07-23 0:50 ` Ihor Solodrai
0 siblings, 1 reply; 21+ messages in thread
From: sashiko-bot @ 2026-07-22 23:48 UTC (permalink / raw)
To: Ihor Solodrai; +Cc: linux-input, bpf, dmitry.torokhov
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Strict aliasing violation via `void **` casting leading to potential Use-After-Free.
--
--- Patch [1]: [PATCH bpf-next v1 1/8] resolve_btfids: Implement generic ensure_mem() to grow arrays ---
commit b5970d9bf6b1262c4ad812706df67f4a14ee5411
Author: Ihor Solodrai <ihor.solodrai@linux.dev>
resolve_btfids: Implement generic ensure_mem() to grow arrays
This commit factors out array growth logic from push_*() helpers into a
generic ensure_mem() macro and function. It uses a void ** cast to update
the array pointer upon reallocation.
> diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
> index f8a91fa7584f4..183466ddc5f97 100644
> --- a/tools/bpf/resolve_btfids/main.c
> +++ b/tools/bpf/resolve_btfids/main.c
> @@ -201,6 +201,35 @@ static int eprintf(int level, int var, const char *fmt, ...)
> #define pr_info(fmt, ...) \
> eprintf(0, verbose, pr_fmt(fmt), ##__VA_ARGS__)
>
> +/*
> + * Grow *data so it can hold at least cnt elements of elem_sz bytes each.
> + * *cap is the capacity in elements and is updated on growth.
> + */
> +static int __ensure_mem(void **data, u32 *cap, u32 cnt, size_t elem_sz)
> +{
> + u32 new_cap, old_cap = *cap;
> + void *arr;
> +
> + if (cnt <= old_cap)
> + return 0;
> +
> + new_cap = max(old_cap + 256, old_cap * 2);
> + if (new_cap < cnt)
> + new_cap = cnt;
> +
> + arr = realloc(*data, elem_sz * new_cap);
> + if (!arr)
> + return -ENOMEM;
> +
> + *data = arr;
[Severity: Medium]
Will this assignment violate strict aliasing rules? Because void * and u32 *
are incompatible types, modifying the pointer through a void ** pointer
violates C strict aliasing.
While core kernel code is compiled with -fno-strict-aliasing, programs under
tools/ are compiled with standard optimizations including -fstrict-aliasing.
If __ensure_mem() is inlined, could the compiler assume that this assignment
does not modify the original typed pointer?
> + *cap = new_cap;
> +
> + return 0;
> +}
> +
> +#define ensure_mem(arr_ptr, cap_ptr, cnt) \
> + __ensure_mem((void **)(arr_ptr), (cap_ptr), (cnt), sizeof(**(arr_ptr)))
[Severity: Medium]
Does casting a typed double pointer (like &ctx->decl_tags which is u32 **) to
void ** here set up the strict aliasing violation mentioned above?
[ ... ]
> @@ -890,17 +919,8 @@ static const struct btf_type *btf_type_skip_qualifiers(const struct btf *btf, s3
>
> static int push_decl_tag_id(struct btf2btf_context *ctx, u32 decl_tag_id)
> {
> - u32 *arr = ctx->decl_tags;
> - u32 cap = ctx->max_decl_tags;
> -
> - if (ctx->nr_decl_tags + 1 > cap) {
> - cap = max(cap + 256, cap * 2);
> - arr = realloc(arr, sizeof(u32) * cap);
> - if (!arr)
> - return -ENOMEM;
> - ctx->max_decl_tags = cap;
> - ctx->decl_tags = arr;
> - }
> + if (ensure_mem(&ctx->decl_tags, &ctx->max_decl_tags, ctx->nr_decl_tags + 1))
> + return -ENOMEM;
>
> ctx->decl_tags[ctx->nr_decl_tags++] = decl_tag_id;
[Severity: Medium]
Could this assignment result in a use-after-free? If the compiler's strict
aliasing optimization assumes ctx->decl_tags was not modified by ensure_mem(),
it might use a cached pointer that was freed by realloc() during the array
assignment.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260722233518.778854-1-ihor.solodrai@linux.dev?part=1
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH bpf-next v1 6/8] HID: bpf: Make syscall kfunc flags match the struct_ops set
2026-07-22 23:35 ` [PATCH bpf-next v1 6/8] HID: bpf: Make syscall kfunc flags match the struct_ops set Ihor Solodrai
@ 2026-07-22 23:49 ` sashiko-bot
2026-07-23 0:52 ` Ihor Solodrai
0 siblings, 1 reply; 21+ messages in thread
From: sashiko-bot @ 2026-07-22 23:49 UTC (permalink / raw)
To: Ihor Solodrai; +Cc: bpf, dmitry.torokhov, linux-input
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] TOCTOU NULL pointer dereference in `dispatch_hid_bpf_device_event` during dynamic HID-BPF attachment.
--
--- Patch [6]: [PATCH bpf-next v1 6/8] HID: bpf: Make syscall kfunc flags match the struct_ops set ---
Note: The format of this review is altered to provide a free-form summary
due to text recitation restrictions. No direct patch diff quoting is used.
commit 460380780bad5817b193c7927dc05e04ce9f5480
Author: Ihor Solodrai <ihor.solodrai@linux.dev>
Subject: HID: bpf: Make syscall kfunc flags match the struct_ops set
This commit updates the kfunc flags for hid_bpf_syscall_kfunc_ids to match
the hid_bpf_kfunc_ids set by adding the KF_SLEEPABLE flag. This ensures
per-kfunc flag consistency across BTF ID sets at build time.
[Severity: High]
This isn't a regression introduced by this patch, but while reviewing the
HID-BPF event dispatching code, a potential time-of-check to time-of-use
issue was noticed in drivers/hid/bpf/hid_bpf_dispatch.c.
Could this sequence lead to a null pointer dereference when a HID-BPF
program is concurrently attached while a device is flooded with input
reports?
In dispatch_hid_bpf_device_event(), the first lockless read of the device
data happens during context initialization:
.data = hdev->bpf.device_data,
Shortly after, a second lockless read is used as a guard:
if (!hdev->bpf.device_data)
return data;
If __hid_bpf_allocate_data() is concurrently executed during a program
attachment, it updates these pointers without memory barriers or taking the
driver_input_lock:
*data = alloc_data;
*size = alloc_size;
If the allocation completes exactly between the two reads in
dispatch_hid_bpf_device_event(), the first read could evaluate to null
while the second read sees the newly allocated pointer and evaluates to
true. This would allow the code to bypass the guard and execute
memset(ctx_kern.data, 0, hdev->bpf.allocated_data) with a null pointer.
Would it be beneficial to use READ_ONCE() or proper synchronization here to
ensure consistent evaluation of the device data pointer?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260722233518.778854-1-ihor.solodrai@linux.dev?part=6
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH bpf-next v1 3/8] resolve_btfids: Keep collected kfuncs in a rbtree
2026-07-22 23:35 ` [PATCH bpf-next v1 3/8] resolve_btfids: Keep collected kfuncs in a rbtree Ihor Solodrai
@ 2026-07-22 23:50 ` sashiko-bot
2026-07-23 0:51 ` Ihor Solodrai
0 siblings, 1 reply; 21+ messages in thread
From: sashiko-bot @ 2026-07-22 23:50 UTC (permalink / raw)
To: Ihor Solodrai; +Cc: linux-input, bpf, dmitry.torokhov
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Silent dismissal of inconsistent kfunc flags during deduplication.
--
--- Patch [3]: [PATCH bpf-next v1 3/8] resolve_btfids: Keep collected kfuncs in a rbtree ---
commit d91e5d0dd32a660902e686ef89cb30a196dda160
Author: Ihor Solodrai <ihor.solodrai@linux.dev>
resolve_btfids: Keep collected kfuncs in a rbtree
This commit changes the storage of collected kfuncs from a dynamically grown
array to an rbtree keyed by BTF ID. This allows for efficient deduplication
when kfuncs are declared in multiple sets.
> diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
> index 3198198b03a78..de4986e1bc3d1 100644
> --- a/tools/bpf/resolve_btfids/main.c
> +++ b/tools/bpf/resolve_btfids/main.c
[ ... ]
> @@ -979,14 +978,48 @@ static int push_decl_tag_id(struct btf2btf_context *ctx, u32 decl_tag_id)
>
> static int push_kfunc(struct btf2btf_context *ctx, struct kfunc *kfunc)
> {
> - if (ensure_mem(&ctx->kfuncs, &ctx->max_kfuncs, ctx->nr_kfuncs + 1))
> + struct rb_node **p = &ctx->kfuncs.rb_node;
> + struct rb_node *parent = NULL;
> + struct kfunc *k;
> +
> + /* Dedup by BTF ID: collecting the same kfunc twice is a no-op. */
> + while (*p) {
> + parent = *p;
> + k = rb_entry(parent, struct kfunc, rb_node);
> +
> + if (kfunc->btf_id < k->btf_id)
> + p = &(*p)->rb_left;
> + else if (kfunc->btf_id > k->btf_id)
> + p = &(*p)->rb_right;
> + else
> + return 0;
[Severity: Medium]
Does this silent return effectively ignore conflicting flags from subsequent
declarations?
If the same kfunc is mistakenly declared in multiple BTF sets with different
flags (such as KF_ACQUIRE vs none), returning 0 here without checking if
k->flags == kfunc->flags will silently discard the incoming flags.
Could this cause critical security flags like KF_ACQUIRE or KF_TRUSTED_ARGS
to be unexpectedly dropped depending on the processing order?
> + }
> +
> + k = zalloc(sizeof(*k));
> + if (!k)
> return -ENOMEM;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260722233518.778854-1-ihor.solodrai@linux.dev?part=3
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH bpf-next v1 8/8] resolve_btfids: Enforce consistent kfunc flags across BTF ID sets
2026-07-22 23:35 ` [PATCH bpf-next v1 8/8] resolve_btfids: Enforce consistent kfunc flags across " Ihor Solodrai
@ 2026-07-23 0:32 ` bot+bpf-ci
0 siblings, 0 replies; 21+ messages in thread
From: bot+bpf-ci @ 2026-07-23 0:32 UTC (permalink / raw)
To: ihor.solodrai, ast, andrii, daniel, eddyz87, memxor
Cc: bentiss, jikos, emil, jolsa, bpf, linux-input, kernel-team, ast,
andrii, daniel, martin.lau, eddyz87, yonghong.song, clm,
ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 600 bytes --]
> Enforce the kfunc flag consistency in resolve_btifds by hard failing
> on error and blocking kernel (or module) build.
This isn't a bug, but should 'resolve_btifds' here be 'resolve_btfids'
to match the tool name?
> [1] https://lore.kernel.org/bpf/9b2196dd-443b-4632-ae11-030cdbdc59b4@linux.dev/
>
> Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/29967476366
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH bpf-next v1 7/8] resolve_btfids: Discover kfuncs from BTF ID sets
2026-07-22 23:35 ` [PATCH bpf-next v1 7/8] resolve_btfids: Discover kfuncs from BTF ID sets Ihor Solodrai
@ 2026-07-23 0:32 ` bot+bpf-ci
2026-07-23 0:57 ` Ihor Solodrai
0 siblings, 1 reply; 21+ messages in thread
From: bot+bpf-ci @ 2026-07-23 0:32 UTC (permalink / raw)
To: ihor.solodrai, ast, andrii, daniel, eddyz87, memxor
Cc: bentiss, jikos, emil, jolsa, bpf, linux-input, kernel-team, ast,
andrii, daniel, martin.lau, eddyz87, yonghong.song, clm,
ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 1382 bytes --]
> collect_kfuncs() currently uses bpf_kfunc decl tags to identify the
> list of kfuncs. The decl tags are generated by pahole, which makes
> current implementation implicitly rely on those tags being generated.
>
> The authoritative source, used by the the BPF verifier for kfunc
> registration, of functions being BPF kfuncs are
> BTF_KFUNCS_START()/END() declarations. These are BTF_ID_SET8 under the
> hood. Currently resolve_btfids reads kfunc flags from these sets, and
> populates them with BTF IDs.
>
> Implement kfunc discovery from BTF_ID_SET8 symbols in resolve_btfids,
> removing the dependency on pahole's emmission of decl tags.
>
> Walk BTF_ID_KIND_SET8 sets, and use the address-to-symbol index to
> look up set entry's BTF_ID symbol name (before .BTF_ids is patched),
> recording the paired flags directly. This makes find_kfunc_flags()
> helper unnecessary, so it's removed.
>
> Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
This isn't a bug, but there are a couple of small typos in the
changelog: "used by the the BPF verifier" has a duplicated "the", and
"pahole's emmission of decl tags" should be "emission".
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/29967476366
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH bpf-next v1 4/8] libbpf: Export btf__find_by_name_kind_own()
2026-07-22 23:43 ` sashiko-bot
@ 2026-07-23 0:45 ` Ihor Solodrai
0 siblings, 0 replies; 21+ messages in thread
From: Ihor Solodrai @ 2026-07-23 0:45 UTC (permalink / raw)
To: sashiko-reviews; +Cc: linux-input, bpf, dmitry.torokhov
On 7/22/26 4:43 PM, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Medium] The newly exposed public libbpf API `btf__find_by_name_kind_own()` lacks the `libbpf_err()` wrapper on its error return path.
> --
>
> --- Patch [4]: [PATCH bpf-next v1 4/8] libbpf: Export btf__find_by_name_kind_own() ---
> commit 60b04eac1753190ac945126aaca0759082942bc0
> Author: Ihor Solodrai <ihor.solodrai@linux.dev>
>
> libbpf: Export btf__find_by_name_kind_own()
>
> btf__find_by_name_kind() searches the base BTF before the split BTF,
> so in case of a name collision between base and split it always
> returns a base type. Tools that process split BTF may need to restrict
> a lookup to the split's own types.
>
> The internal helper btf__find_by_name_kind_own() already does exactly
> that. Make it a public API.
>
>> diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
>> index 1a31f2da947f8..587172c0de089 100644
>> --- a/tools/lib/bpf/btf.h
>> +++ b/tools/lib/bpf/btf.h
>> @@ -172,6 +172,8 @@ LIBBPF_API __s32 btf__find_by_name(const struct btf *btf,
>> const char *type_name);
>> LIBBPF_API __s32 btf__find_by_name_kind(const struct btf *btf,
>> const char *type_name, __u32 kind);
>> +LIBBPF_API __s32 btf__find_by_name_kind_own(const struct btf *btf,
>> + const char *type_name, __u32 kind);
>
> [Severity: Medium]
> Since btf__find_by_name_kind_own() is now a public API, shouldn't its return
> path in tools/lib/bpf/btf.c be updated to use libbpf_err()?
>
> Currently, it returns the value from the internal helper directly:
>
> tools/lib/bpf/btf.c:btf__find_by_name_kind_own() {
> return btf_find_by_name_kind(btf, btf->start_id, type_name, kind);
> }
>
> The libbpf public API error handling contract requires all public API functions
> to set errno using libbpf_err() directly on their return statements. While the
> internal helper btf_find_by_name_kind() currently sets errno indirectly, relying
> on it could cause issues if the internal helper is later fixed to return raw
> error codes.
>
> Should this be updated to return libbpf_err(btf_find_by_name_kind(...))?
Ok clanker, this is embarrassing. Read the code around the diff before posting.
btf__find_by_name_kind_own() mirrors btf__find_by_name_kind(), and
both return btf_find_by_name_kind() directly.
And btf_find_by_name_kind() helper already sets errno via libbpf_err() on its
error paths.
>
>> LIBBPF_API __u32 btf__type_cnt(const struct btf *btf);
>> LIBBPF_API const struct btf *btf__base_btf(const struct btf *btf);
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH bpf-next v1 5/8] resolve_btfids: Fix the _impl lookup for module BTF
2026-07-22 23:35 ` [PATCH bpf-next v1 5/8] resolve_btfids: Fix the _impl lookup for module BTF Ihor Solodrai
@ 2026-07-23 0:46 ` bot+bpf-ci
0 siblings, 0 replies; 21+ messages in thread
From: bot+bpf-ci @ 2026-07-23 0:46 UTC (permalink / raw)
To: ihor.solodrai, ast, andrii, daniel, eddyz87, memxor
Cc: bentiss, jikos, emil, jolsa, bpf, linux-input, kernel-team, ast,
andrii, daniel, martin.lau, eddyz87, yonghong.song, clm,
ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 1010 bytes --]
> resolve_btfids: Fix the _impl lookup for module BTF
>
> process_kfunc_with_implicit_args() skips generating <name>_impl
> function when one already exists for backwards compatibility.
>
> It uses btf__find_by_name_kind(), which searches the base BTF before
> the split BTF. When resolve_btfids processes a module, a same-named
> _impl in vmlinux would be found and the module's own counterpart would
> not be created.
>
> Fix by using btf__find_by_name_kind_own() for the lookup.
>
> Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
The btf__find_by_name_kind() call being changed here was introduced
along with process_kfunc_with_implicit_args() itself. Should this
carry a Fixes: tag?
Fixes: 9d199965990c ("resolve_btfids: Support for KF_IMPLICIT_ARGS")
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/29967476366
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH bpf-next v1 1/8] resolve_btfids: Implement generic ensure_mem() to grow arrays
2026-07-22 23:48 ` sashiko-bot
@ 2026-07-23 0:50 ` Ihor Solodrai
0 siblings, 0 replies; 21+ messages in thread
From: Ihor Solodrai @ 2026-07-23 0:50 UTC (permalink / raw)
To: sashiko-reviews; +Cc: linux-input, bpf, dmitry.torokhov
On 7/22/26 4:48 PM, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Medium] Strict aliasing violation via `void **` casting leading to potential Use-After-Free.
> --
>
> --- Patch [1]: [PATCH bpf-next v1 1/8] resolve_btfids: Implement generic ensure_mem() to grow arrays ---
> commit b5970d9bf6b1262c4ad812706df67f4a14ee5411
> Author: Ihor Solodrai <ihor.solodrai@linux.dev>
>
> resolve_btfids: Implement generic ensure_mem() to grow arrays
>
> This commit factors out array growth logic from push_*() helpers into a
> generic ensure_mem() macro and function. It uses a void ** cast to update
> the array pointer upon reallocation.
>
>> diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
>> index f8a91fa7584f4..183466ddc5f97 100644
>> --- a/tools/bpf/resolve_btfids/main.c
>> +++ b/tools/bpf/resolve_btfids/main.c
>> @@ -201,6 +201,35 @@ static int eprintf(int level, int var, const char *fmt, ...)
>> #define pr_info(fmt, ...) \
>> eprintf(0, verbose, pr_fmt(fmt), ##__VA_ARGS__)
>>
>> +/*
>> + * Grow *data so it can hold at least cnt elements of elem_sz bytes each.
>> + * *cap is the capacity in elements and is updated on growth.
>> + */
>> +static int __ensure_mem(void **data, u32 *cap, u32 cnt, size_t elem_sz)
>> +{
>> + u32 new_cap, old_cap = *cap;
>> + void *arr;
>> +
>> + if (cnt <= old_cap)
>> + return 0;
>> +
>> + new_cap = max(old_cap + 256, old_cap * 2);
>> + if (new_cap < cnt)
>> + new_cap = cnt;
>> +
>> + arr = realloc(*data, elem_sz * new_cap);
>> + if (!arr)
>> + return -ENOMEM;
>> +
>> + *data = arr;
>
> [Severity: Medium]
> Will this assignment violate strict aliasing rules? Because void * and u32 *
> are incompatible types, modifying the pointer through a void ** pointer
> violates C strict aliasing.
>
> While core kernel code is compiled with -fno-strict-aliasing, programs under
> tools/ are compiled with standard optimizations including -fstrict-aliasing.
> If __ensure_mem() is inlined, could the compiler assume that this assignment
> does not modify the original typed pointer?
ensure_mem() is modeled on libbpf's own libbpf_ensure_mem(), which is
called exactly this way throughout libbpf with typed pointers cast to
(void **), built under the same tools/ flags.
The pattern is long-established and hasn't caused issues in practice.
Callers re-read the struct member after the call. Wontfix.
>
>> + *cap = new_cap;
>> +
>> + return 0;
>> +}
>> +
>> +#define ensure_mem(arr_ptr, cap_ptr, cnt) \
>> + __ensure_mem((void **)(arr_ptr), (cap_ptr), (cnt), sizeof(**(arr_ptr)))
>
> [...]
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH bpf-next v1 3/8] resolve_btfids: Keep collected kfuncs in a rbtree
2026-07-22 23:50 ` sashiko-bot
@ 2026-07-23 0:51 ` Ihor Solodrai
0 siblings, 0 replies; 21+ messages in thread
From: Ihor Solodrai @ 2026-07-23 0:51 UTC (permalink / raw)
To: sashiko-reviews; +Cc: linux-input, bpf, dmitry.torokhov
On 7/22/26 4:50 PM, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Medium] Silent dismissal of inconsistent kfunc flags during deduplication.
> --
>
> --- Patch [3]: [PATCH bpf-next v1 3/8] resolve_btfids: Keep collected kfuncs in a rbtree ---
> commit d91e5d0dd32a660902e686ef89cb30a196dda160
> Author: Ihor Solodrai <ihor.solodrai@linux.dev>
>
> resolve_btfids: Keep collected kfuncs in a rbtree
>
> This commit changes the storage of collected kfuncs from a dynamically grown
> array to an rbtree keyed by BTF ID. This allows for efficient deduplication
> when kfuncs are declared in multiple sets.
>
>> diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
>> index 3198198b03a78..de4986e1bc3d1 100644
>> --- a/tools/bpf/resolve_btfids/main.c
>> +++ b/tools/bpf/resolve_btfids/main.c
> [ ... ]
>> @@ -979,14 +978,48 @@ static int push_decl_tag_id(struct btf2btf_context *ctx, u32 decl_tag_id)
>>
>> static int push_kfunc(struct btf2btf_context *ctx, struct kfunc *kfunc)
>> {
>> - if (ensure_mem(&ctx->kfuncs, &ctx->max_kfuncs, ctx->nr_kfuncs + 1))
>> + struct rb_node **p = &ctx->kfuncs.rb_node;
>> + struct rb_node *parent = NULL;
>> + struct kfunc *k;
>> +
>> + /* Dedup by BTF ID: collecting the same kfunc twice is a no-op. */
>> + while (*p) {
>> + parent = *p;
>> + k = rb_entry(parent, struct kfunc, rb_node);
>> +
>> + if (kfunc->btf_id < k->btf_id)
>> + p = &(*p)->rb_left;
>> + else if (kfunc->btf_id > k->btf_id)
>> + p = &(*p)->rb_right;
>> + else
>> + return 0;
>
> [Severity: Medium]
> Does this silent return effectively ignore conflicting flags from subsequent
> declarations?
This is deliberate here. Flags are checked for in the patch #8
>
> If the same kfunc is mistakenly declared in multiple BTF sets with different
> flags (such as KF_ACQUIRE vs none), returning 0 here without checking if
> k->flags == kfunc->flags will silently discard the incoming flags.
>
> Could this cause critical security flags like KF_ACQUIRE or KF_TRUSTED_ARGS
> to be unexpectedly dropped depending on the processing order?
>
>> + }
>> +
>> + k = zalloc(sizeof(*k));
>> + if (!k)
>> return -ENOMEM;
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH bpf-next v1 6/8] HID: bpf: Make syscall kfunc flags match the struct_ops set
2026-07-22 23:49 ` sashiko-bot
@ 2026-07-23 0:52 ` Ihor Solodrai
0 siblings, 0 replies; 21+ messages in thread
From: Ihor Solodrai @ 2026-07-23 0:52 UTC (permalink / raw)
To: sashiko-reviews
Cc: bpf, dmitry.torokhov, linux-input, Benjamin Tissoires,
Jiri Kosina
On 7/22/26 4:49 PM, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
>
> Pre-existing issues:
> - [High] TOCTOU NULL pointer dereference in `dispatch_hid_bpf_device_event` during dynamic HID-BPF attachment.
> --
>
> --- Patch [6]: [PATCH bpf-next v1 6/8] HID: bpf: Make syscall kfunc flags match the struct_ops set ---
> Note: The format of this review is altered to provide a free-form summary
> due to text recitation restrictions. No direct patch diff quoting is used.
>
> commit 460380780bad5817b193c7927dc05e04ce9f5480
> Author: Ihor Solodrai <ihor.solodrai@linux.dev>
> Subject: HID: bpf: Make syscall kfunc flags match the struct_ops set
>
> This commit updates the kfunc flags for hid_bpf_syscall_kfunc_ids to match
> the hid_bpf_kfunc_ids set by adding the KF_SLEEPABLE flag. This ensures
> per-kfunc flag consistency across BTF ID sets at build time.
>
> [Severity: High]
> This isn't a regression introduced by this patch, but while reviewing the
Not relevant to the change.
However HID maintainers may be interested, adding them to cc.
> HID-BPF event dispatching code, a potential time-of-check to time-of-use
> issue was noticed in drivers/hid/bpf/hid_bpf_dispatch.c.
>
> Could this sequence lead to a null pointer dereference when a HID-BPF
> program is concurrently attached while a device is flooded with input
> reports?
>
> In dispatch_hid_bpf_device_event(), the first lockless read of the device
> data happens during context initialization:
>
> .data = hdev->bpf.device_data,
>
> Shortly after, a second lockless read is used as a guard:
>
> if (!hdev->bpf.device_data)
> return data;
>
> If __hid_bpf_allocate_data() is concurrently executed during a program
> attachment, it updates these pointers without memory barriers or taking the
> driver_input_lock:
>
> *data = alloc_data;
> *size = alloc_size;
>
> If the allocation completes exactly between the two reads in
> dispatch_hid_bpf_device_event(), the first read could evaluate to null
> while the second read sees the newly allocated pointer and evaluates to
> true. This would allow the code to bypass the guard and execute
> memset(ctx_kern.data, 0, hdev->bpf.allocated_data) with a null pointer.
>
> Would it be beneficial to use READ_ONCE() or proper synchronization here to
> ensure consistent evaluation of the device data pointer?
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH bpf-next v1 7/8] resolve_btfids: Discover kfuncs from BTF ID sets
2026-07-23 0:32 ` bot+bpf-ci
@ 2026-07-23 0:57 ` Ihor Solodrai
0 siblings, 0 replies; 21+ messages in thread
From: Ihor Solodrai @ 2026-07-23 0:57 UTC (permalink / raw)
To: bot+bpf-ci, ast, andrii, daniel, eddyz87, memxor
Cc: bentiss, jikos, emil, jolsa, bpf, linux-input, kernel-team,
martin.lau, yonghong.song, clm
On 7/22/26 5:32 PM, bot+bpf-ci@kernel.org wrote:
>> collect_kfuncs() currently uses bpf_kfunc decl tags to identify the
>> list of kfuncs. The decl tags are generated by pahole, which makes
>> current implementation implicitly rely on those tags being generated.
>>
>> The authoritative source, used by the the BPF verifier for kfunc
>> registration, of functions being BPF kfuncs are
>> BTF_KFUNCS_START()/END() declarations. These are BTF_ID_SET8 under the
>> hood. Currently resolve_btfids reads kfunc flags from these sets, and
>> populates them with BTF IDs.
>>
>> Implement kfunc discovery from BTF_ID_SET8 symbols in resolve_btfids,
>> removing the dependency on pahole's emmission of decl tags.
>>
>> Walk BTF_ID_KIND_SET8 sets, and use the address-to-symbol index to
>> look up set entry's BTF_ID symbol name (before .BTF_ids is patched),
>> recording the paired flags directly. This makes find_kfunc_flags()
>> helper unnecessary, so it's removed.
>>
>> Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
>
> This isn't a bug, but there are a couple of small typos in the
> changelog: "used by the the BPF verifier" has a duplicated "the", and
> "pahole's emmission of decl tags" should be "emission".
I guess typos don't count as proof-of-human-typing, because AI can be
instructed to make typos :) Will fix.
>
>
> ---
> AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
>
> CI run summary: https://github.com/kernel-patches/bpf/actions/runs/29967476366
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2026-07-23 0:57 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-22 23:35 [PATCH bpf-next v1 0/8] resolve_btfids: Discover kfuncs from BTF ID sets Ihor Solodrai
2026-07-22 23:35 ` [PATCH bpf-next v1 1/8] resolve_btfids: Implement generic ensure_mem() to grow arrays Ihor Solodrai
2026-07-22 23:48 ` sashiko-bot
2026-07-23 0:50 ` Ihor Solodrai
2026-07-22 23:35 ` [PATCH bpf-next v1 2/8] resolve_btfids: Index BTF ID symbols by address Ihor Solodrai
2026-07-22 23:35 ` [PATCH bpf-next v1 3/8] resolve_btfids: Keep collected kfuncs in a rbtree Ihor Solodrai
2026-07-22 23:50 ` sashiko-bot
2026-07-23 0:51 ` Ihor Solodrai
2026-07-22 23:35 ` [PATCH bpf-next v1 4/8] libbpf: Export btf__find_by_name_kind_own() Ihor Solodrai
2026-07-22 23:43 ` sashiko-bot
2026-07-23 0:45 ` Ihor Solodrai
2026-07-22 23:35 ` [PATCH bpf-next v1 5/8] resolve_btfids: Fix the _impl lookup for module BTF Ihor Solodrai
2026-07-23 0:46 ` bot+bpf-ci
2026-07-22 23:35 ` [PATCH bpf-next v1 6/8] HID: bpf: Make syscall kfunc flags match the struct_ops set Ihor Solodrai
2026-07-22 23:49 ` sashiko-bot
2026-07-23 0:52 ` Ihor Solodrai
2026-07-22 23:35 ` [PATCH bpf-next v1 7/8] resolve_btfids: Discover kfuncs from BTF ID sets Ihor Solodrai
2026-07-23 0:32 ` bot+bpf-ci
2026-07-23 0:57 ` Ihor Solodrai
2026-07-22 23:35 ` [PATCH bpf-next v1 8/8] resolve_btfids: Enforce consistent kfunc flags across " Ihor Solodrai
2026-07-23 0:32 ` bot+bpf-ci
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.