All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH bpf-next v1 0/4] Modernize resolve_btfids selftest
@ 2026-06-17 21:06 Ihor Solodrai
  2026-06-17 21:06 ` [PATCH bpf-next v1 1/4] tools/bpf: Sync btf_ids.h to tools Ihor Solodrai
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Ihor Solodrai @ 2026-06-17 21:06 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf, linux-kbuild

This series updates resolve_btfids selftests to use latest selftest
helpers API and add kfunc set testing.

This series was split from a bigger series [1].  It's general selftest
improvements that don't have to be entangled with resolve_btfids
development, and makes the main series a bit smaller.

[1] https://lore.kernel.org/bpf/20260601221805.821394-1-ihor.solodrai@linux.dev/

Changes compared to original 4 patches:
  * various nits from Jiri, Andrii and Emil
  * in patch #3 (that adds gcc pragma) definitions are moved such that
    .local BTF_ID_* containers are grouped together and we have a
    single pragma scope

---

Ihor Solodrai (4):
  tools/bpf: Sync btf_ids.h to tools
  selftests/bpf: Modernize resolve_btfids test scaffolding
  selftests/bpf: Fix resolve_btfids test reads of BTF ID sets in PIE
    builds
  selftests/bpf: Add kfunc set test to resolve_btfids

 tools/include/linux/btf_ids.h                 |  78 +++++++++-
 .../selftests/bpf/prog_tests/resolve_btfids.c | 140 ++++++++++++------
 tools/testing/selftests/bpf/progs/btf_data.c  |  10 ++
 3 files changed, 177 insertions(+), 51 deletions(-)

-- 
2.54.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH bpf-next v1 1/4] tools/bpf: Sync btf_ids.h to tools
  2026-06-17 21:06 [PATCH bpf-next v1 0/4] Modernize resolve_btfids selftest Ihor Solodrai
@ 2026-06-17 21:06 ` Ihor Solodrai
  2026-06-17 21:06 ` [PATCH bpf-next v1 2/4] selftests/bpf: Modernize resolve_btfids test scaffolding Ihor Solodrai
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Ihor Solodrai @ 2026-06-17 21:06 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf, linux-kbuild

Sync tools/include/linux/btf_ids.h with include/linux/btf_ids.h so
tools-side code can use BTF_ID_FLAGS(), BTF_SET8_START(), and
BTF_KFUNCS_START().

Keep the tools copy's existing compiler header dependency:
tools/include/linux/compiler.h already provides __maybe_unused and
tools/include/linux/compiler_attributes.h does not exist.

Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/include/linux/btf_ids.h | 78 ++++++++++++++++++++++++++++++++---
 1 file changed, 73 insertions(+), 5 deletions(-)

diff --git a/tools/include/linux/btf_ids.h b/tools/include/linux/btf_ids.h
index 72ea363d434d..4fe5c5f1558c 100644
--- a/tools/include/linux/btf_ids.h
+++ b/tools/include/linux/btf_ids.h
@@ -10,6 +10,9 @@ struct btf_id_set {
 	u32 ids[];
 };
 
+/* This flag implies BTF_SET8 holds kfunc(s) */
+#define BTF_SET8_KFUNCS		(1 << 0)
+
 struct btf_id_set8 {
 	u32 cnt;
 	u32 flags;
@@ -22,6 +25,7 @@ struct btf_id_set8 {
 #ifdef CONFIG_DEBUG_INFO_BTF
 
 #include <linux/compiler.h> /* for __PASTE */
+#include <linux/stringify.h>
 
 /*
  * Following macros help to define lists of BTF IDs placed
@@ -35,7 +39,7 @@ struct btf_id_set8 {
 
 #define BTF_IDS_SECTION ".BTF_ids"
 
-#define ____BTF_ID(symbol)				\
+#define ____BTF_ID(symbol, word)			\
 asm(							\
 ".pushsection " BTF_IDS_SECTION ",\"a\";       \n"	\
 ".local " #symbol " ;                          \n"	\
@@ -43,10 +47,11 @@ asm(							\
 ".size  " #symbol ", 4;                        \n"	\
 #symbol ":                                     \n"	\
 ".zero 4                                       \n"	\
+word							\
 ".popsection;                                  \n");
 
-#define __BTF_ID(symbol) \
-	____BTF_ID(symbol)
+#define __BTF_ID(symbol, word) \
+	____BTF_ID(symbol, word)
 
 #define __ID(prefix) \
 	__PASTE(__PASTE(prefix, __COUNTER__), __LINE__)
@@ -56,7 +61,14 @@ asm(							\
  * to 4 zero bytes.
  */
 #define BTF_ID(prefix, name) \
-	__BTF_ID(__ID(__BTF_ID__##prefix##__##name##__))
+	__BTF_ID(__ID(__BTF_ID__##prefix##__##name##__), "")
+
+#define ____BTF_ID_FLAGS(prefix, name, flags) \
+	__BTF_ID(__ID(__BTF_ID__##prefix##__##name##__), ".long " #flags "\n")
+#define __BTF_ID_FLAGS(prefix, name, flags, ...) \
+	____BTF_ID_FLAGS(prefix, name, flags)
+#define BTF_ID_FLAGS(prefix, name, ...) \
+	__BTF_ID_FLAGS(prefix, name, ##__VA_ARGS__, 0)
 
 /*
  * The BTF_ID_LIST macro defines pure (unsorted) list
@@ -155,10 +167,58 @@ asm(							\
 ".popsection;                                 \n");	\
 extern struct btf_id_set name;
 
+/*
+ * The BTF_SET8_START/END macros pair defines sorted list of
+ * BTF IDs and their flags plus its members count, with the
+ * following layout:
+ *
+ * BTF_SET8_START(list)
+ * BTF_ID_FLAGS(type1, name1, flags)
+ * BTF_ID_FLAGS(type2, name2, flags)
+ * BTF_SET8_END(list)
+ *
+ * __BTF_ID__set8__list:
+ * .zero 8
+ * list:
+ * __BTF_ID__type1__name1__3:
+ * .zero 4
+ * .word (1 << 0) | (1 << 2)
+ * __BTF_ID__type2__name2__5:
+ * .zero 4
+ * .word (1 << 3) | (1 << 1) | (1 << 2)
+ *
+ */
+#define __BTF_SET8_START(name, scope, flags)		\
+__BTF_ID_LIST(name, local)				\
+asm(							\
+".pushsection " BTF_IDS_SECTION ",\"a\";       \n"	\
+"." #scope " __BTF_ID__set8__" #name ";        \n"	\
+"__BTF_ID__set8__" #name ":;                   \n"	\
+".zero 4                                       \n"	\
+".long " __stringify(flags)                   "\n"	\
+".popsection;                                  \n");
+
+#define BTF_SET8_START(name)				\
+__BTF_SET8_START(name, local, 0)
+
+#define BTF_SET8_END(name)				\
+asm(							\
+".pushsection " BTF_IDS_SECTION ",\"a\";      \n"	\
+".size __BTF_ID__set8__" #name ", .-" #name "  \n"	\
+".popsection;                                 \n");	\
+extern struct btf_id_set8 name;
+
+#define BTF_KFUNCS_START(name)				\
+__BTF_SET8_START(name, local, BTF_SET8_KFUNCS)
+
+#define BTF_KFUNCS_END(name)				\
+BTF_SET8_END(name)
+
 #else
 
-#define BTF_ID_LIST(name) static u32 __maybe_unused name[5];
+#define BTF_ID_LIST(name) static u32 __maybe_unused name[128];
 #define BTF_ID(prefix, name)
+#define BTF_ID_FLAGS(prefix, name, ...)
 #define BTF_ID_UNUSED
 #define BTF_ID_LIST_GLOBAL(name, n) u32 __maybe_unused name[n];
 #define BTF_ID_LIST_SINGLE(name, prefix, typename) static u32 __maybe_unused name[1];
@@ -166,6 +226,10 @@ extern struct btf_id_set name;
 #define BTF_SET_START(name) static struct btf_id_set __maybe_unused name = { 0 };
 #define BTF_SET_START_GLOBAL(name) static struct btf_id_set __maybe_unused name = { 0 };
 #define BTF_SET_END(name)
+#define BTF_SET8_START(name) static struct btf_id_set8 __maybe_unused name = { 0 };
+#define BTF_SET8_END(name)
+#define BTF_KFUNCS_START(name) static struct btf_id_set8 __maybe_unused name = { .flags = BTF_SET8_KFUNCS };
+#define BTF_KFUNCS_END(name)
 
 #endif /* CONFIG_DEBUG_INFO_BTF */
 
@@ -215,5 +279,9 @@ MAX_BTF_TRACING_TYPE,
 };
 
 extern u32 btf_tracing_ids[];
+extern u32 bpf_cgroup_btf_id[];
+extern u32 bpf_local_storage_map_btf_id[];
+extern u32 btf_bpf_map_id[];
+extern u32 bpf_kmem_cache_btf_id[];
 
 #endif
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH bpf-next v1 2/4] selftests/bpf: Modernize resolve_btfids test scaffolding
  2026-06-17 21:06 [PATCH bpf-next v1 0/4] Modernize resolve_btfids selftest Ihor Solodrai
  2026-06-17 21:06 ` [PATCH bpf-next v1 1/4] tools/bpf: Sync btf_ids.h to tools Ihor Solodrai
@ 2026-06-17 21:06 ` Ihor Solodrai
  2026-06-17 21:06 ` [PATCH bpf-next v1 3/4] selftests/bpf: Fix resolve_btfids test reads of BTF ID sets in PIE builds Ihor Solodrai
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Ihor Solodrai @ 2026-06-17 21:06 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf, linux-kbuild

Refactor resolve_btfids test in order to:
  * use newer ASSERT_* macros instead of CHECK
  * extend the lifetime of loaded BTF to enable additional checks
  * cleanup unused/unnecessary code

Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 .../selftests/bpf/prog_tests/resolve_btfids.c | 60 +++++++------------
 1 file changed, 20 insertions(+), 40 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c b/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
index 41dfaaabb73f..e549780697c7 100644
--- a/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
+++ b/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
@@ -10,7 +10,7 @@
 #include <linux/btf_ids.h>
 #include "test_progs.h"
 
-static int duration;
+#define BTF_DATA_FILE "resolve_btfids.test.o.BTF"
 
 struct symbol {
 	const char	*name;
@@ -70,10 +70,8 @@ __resolve_symbol(struct btf *btf, int type_id)
 	unsigned int i;
 
 	type = btf__type_by_id(btf, type_id);
-	if (!type) {
-		PRINT_FAIL("Failed to get type for ID %d\n", type_id);
+	if (!ASSERT_OK_PTR(type, "btf__type_by_id"))
 		return -1;
-	}
 
 	for (i = 0; i < ARRAY_SIZE(test_symbols); i++) {
 		if (test_symbols[i].id >= 0)
@@ -83,10 +81,8 @@ __resolve_symbol(struct btf *btf, int type_id)
 			continue;
 
 		str = btf__name_by_offset(btf, type->name_off);
-		if (!str) {
-			PRINT_FAIL("Failed to get name for BTF ID %d\n", type_id);
+		if (!ASSERT_OK_PTR(str, "btf__name_by_offset"))
 			return -1;
-		}
 
 		if (!strcmp(str, test_symbols[i].name))
 			test_symbols[i].id = type_id;
@@ -95,25 +91,15 @@ __resolve_symbol(struct btf *btf, int type_id)
 	return 0;
 }
 
-static int resolve_symbols(void)
+static int resolve_symbols(struct btf *btf)
 {
-	struct btf *btf;
+	__u32 nr = btf__type_cnt(btf);
 	int type_id;
-	__u32 nr;
-
-	btf = btf__parse_raw("resolve_btfids.test.o.BTF");
-	if (CHECK(libbpf_get_error(btf), "resolve",
-		  "Failed to load BTF from resolve_btfids.test.o.BTF\n"))
-		return -1;
-
-	nr = btf__type_cnt(btf);
 
 	for (type_id = 1; type_id < nr; type_id++) {
 		if (__resolve_symbol(btf, type_id))
-			break;
+			return -1;
 	}
-
-	btf__free(btf);
 	return 0;
 }
 
@@ -121,25 +107,22 @@ void test_resolve_btfids(void)
 {
 	__u32 *test_list, *test_lists[] = { test_list_local, test_list_global };
 	unsigned int i, j;
-	int ret = 0;
+	struct btf *btf;
 
-	if (resolve_symbols())
+	btf = btf__parse_raw(BTF_DATA_FILE);
+	if (!ASSERT_OK_PTR(btf, "btf_parse"))
 		return;
 
+	if (resolve_symbols(btf))
+		goto out;
+
 	/* Check BTF_ID_LIST(test_list_local) and
 	 * BTF_ID_LIST_GLOBAL(test_list_global) IDs
 	 */
 	for (j = 0; j < ARRAY_SIZE(test_lists); j++) {
 		test_list = test_lists[j];
-		for (i = 0; i < ARRAY_SIZE(test_symbols); i++) {
-			ret = CHECK(test_list[i] != test_symbols[i].id,
-				    "id_check",
-				    "wrong ID for %s (%d != %d)\n",
-				    test_symbols[i].name,
-				    test_list[i], test_symbols[i].id);
-			if (ret)
-				return;
-		}
+		for (i = 0; i < ARRAY_SIZE(test_symbols); i++)
+			ASSERT_EQ(test_list[i], test_symbols[i].id, test_symbols[i].name);
 	}
 
 	/* Check BTF_SET_START(test_set) IDs */
@@ -153,15 +136,12 @@ void test_resolve_btfids(void)
 			break;
 		}
 
-		ret = CHECK(!found, "id_check",
-			    "ID %d not found in test_symbols\n",
-			    test_set.ids[i]);
-		if (ret)
-			break;
+		ASSERT_TRUE(found, "id_in_test_symbols");
 
-		if (i > 0) {
-			if (!ASSERT_LE(test_set.ids[i - 1], test_set.ids[i], "sort_check"))
-				return;
-		}
+		if (i > 0)
+			ASSERT_LE(test_set.ids[i - 1], test_set.ids[i], "sort_check");
 	}
+
+out:
+	btf__free(btf);
 }
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH bpf-next v1 3/4] selftests/bpf: Fix resolve_btfids test reads of BTF ID sets in PIE builds
  2026-06-17 21:06 [PATCH bpf-next v1 0/4] Modernize resolve_btfids selftest Ihor Solodrai
  2026-06-17 21:06 ` [PATCH bpf-next v1 1/4] tools/bpf: Sync btf_ids.h to tools Ihor Solodrai
  2026-06-17 21:06 ` [PATCH bpf-next v1 2/4] selftests/bpf: Modernize resolve_btfids test scaffolding Ihor Solodrai
@ 2026-06-17 21:06 ` Ihor Solodrai
  2026-06-17 21:06 ` [PATCH bpf-next v1 4/4] selftests/bpf: Add kfunc set test to resolve_btfids Ihor Solodrai
  2026-06-18 12:32 ` [PATCH bpf-next v1 0/4] Modernize resolve_btfids selftest Jiri Olsa
  4 siblings, 0 replies; 7+ messages in thread
From: Ihor Solodrai @ 2026-06-17 21:06 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf, linux-kbuild

TL;DR

On aarch64 with gcc toolchain, when test_progs is linked as a PIE,
reads of BTF ID array by C name return garbage because the GNU
assembler on aarch64 unconditionally folds .local symbol references
into section+addend form, and GOT slots cannot carry an addend per the
AArch64 ELF spec.

Fix by marking the test's BTF ID objects with hidden visibility, which
makes gcc emit a direct access that bypasses the GOT entirely.

Details below.

The subsequent patches adding kfunc checks to resolve_btfids test may
cause test failures on aarch64 / gcc-15:

  test_resolve_btfids:FAIL:kfunc_set_flags  actual 13 != expected 1
  test_resolve_btfids:FAIL:kfunc_set_cnt    actual 0  != expected 4

The test defines its BTF ID sets with the same macros as the kernel
and reads them back directly by C name (in the same way as the kernel
code does).

test_kfunc_set is a .local symbol emitted into .BTF_ids by inline asm
and declared to the compiler as a plain default-visibility
extern, that is:
    extern struct btf_id_set8 test_kfunc_set;

Depending on the build environment, test_progs may be linked as a
position-independent executable (for example, gcc defaults to -fpie
[1]). In a PIE, taking the address of a default-visibility extern is
routed through the GOT (Global Offset Table) [2].

The GNU assembler's adjust_reloc_syms() pass (gas/write.c [3])
replaces references to local symbols with the corresponding section
symbol, folding the symbol's offset into the relocation addend.  On
aarch64 this conversion is unconditional: tc_fix_adjustable() is
defined to 1 for all fixups (gas/config/tc-aarch64.h [4]), so even
GOT-generating relocations are subject to it.  The resulting object
file therefore contains:

  R_AARCH64_ADR_GOT_PAGE      .BTF_ids + 0x54
  R_AARCH64_LD64_GOT_LO12_NC  .BTF_ids + 0x54

However, the AArch64 ELF specification mandates that GOT-generating
relocations must have a zero addend [5].  The +0x54 is therefore not
honored: the linker creates a GOT slot pointing at the .BTF_ids base,
and every access through that slot reads offset 0 instead of 0x54.

This is purely a read-side problem, specific to the PIE test binary on
aarch64 with gcc toolchain. resolve_btfids patches the set header
correctly and the .BTF_ids bytes in test_progs are correct. vmlinux is
unaffected because it is built with -fno-PIE [6] and reaches .BTF_ids
with direct, addend-preserving relocations rather than the GOT. clang
is unaffected because LLVM's assembler retains the original symbol for
GOT relocations instead of converting to section+addend [7].

To mitigate this issue, mark the test's .local BTF ID objects
(test_list_local and test_set) hidden with a visibility pragma so that
gcc treats them as non-interposable and emits a direct access instead
of a GOT load. test_list_global is .globl, which the assembler does not
fold into section+addend, so it is left at default visibility. This
keeps the natural by-name access, works in both PIE and non-PIE builds,
and needs no change to the BTF_ID macros or resolve_btfids.

[1] https://gcc.gnu.org/onlinedocs/gnat_ugn/Position-Independent-Executable-PIE-Enabled-by-Default-on-Linux.html
[2] https://gcc.gnu.org/wiki/Visibility
[3] https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gas/write.c#l922
[4] https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gas/config/tc-aarch64.h#l279
[5] https://github.com/ARM-software/abi-aa/blob/main/aaelf64/aaelf64.rst#5733relocation-operations
[6] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Makefile?h=v7.1-rc6#n593
[7] https://github.com/llvm/llvm-project/blob/4b3bc46d1d794b8ed78b75ccd35a6cc30235bf31/llvm/lib/MC/ELFObjectWriter.cpp#L1213-L1224

Acked-by: Andrii Nakryiko <andrii@kernel.org>
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 .../selftests/bpf/prog_tests/resolve_btfids.c | 29 +++++++++++++++----
 1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c b/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
index e549780697c7..6bcadee50bb8 100644
--- a/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
+++ b/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
@@ -34,6 +34,24 @@ asm (
 ".balign 4, 0;                            \n"
 ".popsection;                             \n");
 
+/*
+ * test_list_local and test_set are .local symbols placed in .BTF_ids by
+ * inline asm, and are read here directly by C name. To the compiler they
+ * are plain, default-visibility extern objects.
+ *
+ * When test_progs is linked as a position-independent executable (PIE),
+ * taking the address of such an extern is routed through the GOT. The
+ * GNU assembler on aarch64 unconditionally converts references to .local
+ * symbols into section + addend form (".BTF_ids + <offset>"), but a GOT
+ * slot cannot carry an addend (the AArch64 ELF spec mandates zero), so
+ * the linker resolves it to the .BTF_ids base.
+ *
+ * Mark them hidden so the compiler treats them as non-interposable and
+ * emits a direct, addend-preserving PC-relative access instead of a GOT
+ * load, in both PIE and non-PIE builds. test_list_global is .globl and
+ * not affected, so it is left at default visibility.
+ */
+#pragma GCC visibility push(hidden)
 BTF_ID_LIST(test_list_local)
 BTF_ID_UNUSED
 BTF_ID(typedef, S)
@@ -43,24 +61,25 @@ BTF_ID(struct,  S)
 BTF_ID(union,   U)
 BTF_ID(func,    func)
 
-extern __u32 test_list_global[];
-BTF_ID_LIST_GLOBAL(test_list_global, 1)
-BTF_ID_UNUSED
+BTF_SET_START(test_set)
 BTF_ID(typedef, S)
 BTF_ID(typedef, T)
 BTF_ID(typedef, U)
 BTF_ID(struct,  S)
 BTF_ID(union,   U)
 BTF_ID(func,    func)
+BTF_SET_END(test_set)
+#pragma GCC visibility pop
 
-BTF_SET_START(test_set)
+extern __u32 test_list_global[];
+BTF_ID_LIST_GLOBAL(test_list_global, 1)
+BTF_ID_UNUSED
 BTF_ID(typedef, S)
 BTF_ID(typedef, T)
 BTF_ID(typedef, U)
 BTF_ID(struct,  S)
 BTF_ID(union,   U)
 BTF_ID(func,    func)
-BTF_SET_END(test_set)
 
 static int
 __resolve_symbol(struct btf *btf, int type_id)
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH bpf-next v1 4/4] selftests/bpf: Add kfunc set test to resolve_btfids
  2026-06-17 21:06 [PATCH bpf-next v1 0/4] Modernize resolve_btfids selftest Ihor Solodrai
                   ` (2 preceding siblings ...)
  2026-06-17 21:06 ` [PATCH bpf-next v1 3/4] selftests/bpf: Fix resolve_btfids test reads of BTF ID sets in PIE builds Ihor Solodrai
@ 2026-06-17 21:06 ` Ihor Solodrai
  2026-06-18 12:31   ` Jiri Olsa
  2026-06-18 12:32 ` [PATCH bpf-next v1 0/4] Modernize resolve_btfids selftest Jiri Olsa
  4 siblings, 1 reply; 7+ messages in thread
From: Ihor Solodrai @ 2026-06-17 21:06 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf, linux-kbuild

Extend the resolve_btfids selftest to cover kfunc sets defined with
BTF_KFUNCS_START/BTF_KFUNCS_END.

The test verifies that resolve_btfids correctly processes BTF_ID_FLAGS,
resolves function IDs, and checks the kfunc set is sorted.

Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 .../selftests/bpf/prog_tests/resolve_btfids.c | 63 ++++++++++++++++---
 tools/testing/selftests/bpf/progs/btf_data.c  | 10 +++
 2 files changed, 66 insertions(+), 7 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c b/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
index 6bcadee50bb8..65ede3ac5845 100644
--- a/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
+++ b/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
@@ -12,6 +12,10 @@
 
 #define BTF_DATA_FILE "resolve_btfids.test.o.BTF"
 
+#ifndef KF_FASTCALL
+#define KF_FASTCALL (1 << 12)
+#endif
+
 struct symbol {
 	const char	*name;
 	int		 type;
@@ -28,6 +32,17 @@ struct symbol test_symbols[] = {
 	{ "func",    BTF_KIND_FUNC,    -1 },
 };
 
+struct kfunc_symbol {
+	const char	*name;
+	s32		 id;
+	u32		 flags;
+};
+
+static struct kfunc_symbol kfunc_symbols[] = {
+	{ "kfunc_a", -1, 0 },
+	{ "kfunc_b", -1, KF_FASTCALL },
+};
+
 /* Align the .BTF_ids section to 4 bytes */
 asm (
 ".pushsection " BTF_IDS_SECTION " ,\"a\"; \n"
@@ -35,9 +50,9 @@ asm (
 ".popsection;                             \n");
 
 /*
- * test_list_local and test_set are .local symbols placed in .BTF_ids by
- * inline asm, and are read here directly by C name. To the compiler they
- * are plain, default-visibility extern objects.
+ * test_list_local, test_set and test_kfunc_set are .local symbols placed
+ * in .BTF_ids by inline asm, and are read here directly by C name. To the
+ * compiler they are plain, default-visibility extern objects.
  *
  * When test_progs is linked as a position-independent executable (PIE),
  * taking the address of such an extern is routed through the GOT. The
@@ -69,6 +84,11 @@ BTF_ID(struct,  S)
 BTF_ID(union,   U)
 BTF_ID(func,    func)
 BTF_SET_END(test_set)
+
+BTF_KFUNCS_START(test_kfunc_set)
+BTF_ID_FLAGS(func, kfunc_a)
+BTF_ID_FLAGS(func, kfunc_b, KF_FASTCALL)
+BTF_KFUNCS_END(test_kfunc_set)
 #pragma GCC visibility pop
 
 extern __u32 test_list_global[];
@@ -92,6 +112,8 @@ __resolve_symbol(struct btf *btf, int type_id)
 	if (!ASSERT_OK_PTR(type, "btf__type_by_id"))
 		return -1;
 
+	str = btf__name_by_offset(btf, type->name_off);
+
 	for (i = 0; i < ARRAY_SIZE(test_symbols); i++) {
 		if (test_symbols[i].id >= 0)
 			continue;
@@ -99,14 +121,20 @@ __resolve_symbol(struct btf *btf, int type_id)
 		if (BTF_INFO_KIND(type->info) != test_symbols[i].type)
 			continue;
 
-		str = btf__name_by_offset(btf, type->name_off);
-		if (!ASSERT_OK_PTR(str, "btf__name_by_offset"))
-			return -1;
-
 		if (!strcmp(str, test_symbols[i].name))
 			test_symbols[i].id = type_id;
 	}
 
+	if (!btf_is_func(type))
+		return 0;
+
+	for (i = 0; i < ARRAY_SIZE(kfunc_symbols); i++) {
+		if (kfunc_symbols[i].id >= 0)
+			continue;
+		if (!strcmp(str, kfunc_symbols[i].name))
+			kfunc_symbols[i].id = type_id;
+	}
+
 	return 0;
 }
 
@@ -161,6 +189,27 @@ void test_resolve_btfids(void)
 			ASSERT_LE(test_set.ids[i - 1], test_set.ids[i], "sort_check");
 	}
 
+	/* Check BTF_KFUNCS_START(test_kfunc_set) */
+	ASSERT_EQ(test_kfunc_set.flags, BTF_SET8_KFUNCS, "kfunc_set_flags");
+	ASSERT_EQ(test_kfunc_set.cnt, ARRAY_SIZE(kfunc_symbols), "kfunc_set_cnt");
+
+	for (i = 0; i < test_kfunc_set.cnt; i++) {
+		for (j = 0; j < ARRAY_SIZE(kfunc_symbols); j++) {
+			if (kfunc_symbols[j].id == (s32)test_kfunc_set.pairs[i].id) {
+				ASSERT_EQ(test_kfunc_set.pairs[i].flags,
+					  kfunc_symbols[j].flags, "kfunc_flags_check");
+				break;
+			}
+		}
+
+		ASSERT_TRUE(j < ARRAY_SIZE(kfunc_symbols), "kfunc_id_found");
+
+		if (i > 0) {
+			ASSERT_LE(test_kfunc_set.pairs[i - 1].id,
+				  test_kfunc_set.pairs[i].id, "kfunc_sort_check");
+		}
+	}
+
 out:
 	btf__free(btf);
 }
diff --git a/tools/testing/selftests/bpf/progs/btf_data.c b/tools/testing/selftests/bpf/progs/btf_data.c
index baa525275bde..8587658012c3 100644
--- a/tools/testing/selftests/bpf/progs/btf_data.c
+++ b/tools/testing/selftests/bpf/progs/btf_data.c
@@ -48,3 +48,13 @@ int func(struct root_struct *root)
 {
 	return 0;
 }
+
+int kfunc_a(struct root_struct *root)
+{
+	return 0;
+}
+
+int kfunc_b(struct root_struct *root)
+{
+	return 0;
+}
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH bpf-next v1 4/4] selftests/bpf: Add kfunc set test to resolve_btfids
  2026-06-17 21:06 ` [PATCH bpf-next v1 4/4] selftests/bpf: Add kfunc set test to resolve_btfids Ihor Solodrai
@ 2026-06-18 12:31   ` Jiri Olsa
  0 siblings, 0 replies; 7+ messages in thread
From: Jiri Olsa @ 2026-06-18 12:31 UTC (permalink / raw)
  To: Ihor Solodrai
  Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi, Alan Maguire,
	Emil Tsalapatis, bpf, linux-kbuild

On Wed, Jun 17, 2026 at 02:06:19PM -0700, Ihor Solodrai wrote:
> Extend the resolve_btfids selftest to cover kfunc sets defined with
> BTF_KFUNCS_START/BTF_KFUNCS_END.
> 
> The test verifies that resolve_btfids correctly processes BTF_ID_FLAGS,
> resolves function IDs, and checks the kfunc set is sorted.
> 
> Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
> Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
> ---
>  .../selftests/bpf/prog_tests/resolve_btfids.c | 63 ++++++++++++++++---
>  tools/testing/selftests/bpf/progs/btf_data.c  | 10 +++
>  2 files changed, 66 insertions(+), 7 deletions(-)
> 
> diff --git a/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c b/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
> index 6bcadee50bb8..65ede3ac5845 100644
> --- a/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
> +++ b/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
> @@ -12,6 +12,10 @@
>  
>  #define BTF_DATA_FILE "resolve_btfids.test.o.BTF"
>  
> +#ifndef KF_FASTCALL
> +#define KF_FASTCALL (1 << 12)
> +#endif
> +
>  struct symbol {
>  	const char	*name;
>  	int		 type;
> @@ -28,6 +32,17 @@ struct symbol test_symbols[] = {
>  	{ "func",    BTF_KIND_FUNC,    -1 },
>  };
>  
> +struct kfunc_symbol {
> +	const char	*name;
> +	s32		 id;
> +	u32		 flags;
> +};
> +
> +static struct kfunc_symbol kfunc_symbols[] = {
> +	{ "kfunc_a", -1, 0 },
> +	{ "kfunc_b", -1, KF_FASTCALL },
> +};
> +
>  /* Align the .BTF_ids section to 4 bytes */
>  asm (
>  ".pushsection " BTF_IDS_SECTION " ,\"a\"; \n"
> @@ -35,9 +50,9 @@ asm (
>  ".popsection;                             \n");
>  
>  /*
> - * test_list_local and test_set are .local symbols placed in .BTF_ids by
> - * inline asm, and are read here directly by C name. To the compiler they
> - * are plain, default-visibility extern objects.
> + * test_list_local, test_set and test_kfunc_set are .local symbols placed
> + * in .BTF_ids by inline asm, and are read here directly by C name. To the
> + * compiler they are plain, default-visibility extern objects.
>   *
>   * When test_progs is linked as a position-independent executable (PIE),
>   * taking the address of such an extern is routed through the GOT. The
> @@ -69,6 +84,11 @@ BTF_ID(struct,  S)
>  BTF_ID(union,   U)
>  BTF_ID(func,    func)
>  BTF_SET_END(test_set)
> +
> +BTF_KFUNCS_START(test_kfunc_set)
> +BTF_ID_FLAGS(func, kfunc_a)
> +BTF_ID_FLAGS(func, kfunc_b, KF_FASTCALL)
> +BTF_KFUNCS_END(test_kfunc_set)
>  #pragma GCC visibility pop
>  
>  extern __u32 test_list_global[];
> @@ -92,6 +112,8 @@ __resolve_symbol(struct btf *btf, int type_id)
>  	if (!ASSERT_OK_PTR(type, "btf__type_by_id"))
>  		return -1;
>  
> +	str = btf__name_by_offset(btf, type->name_off);

should we assert str != NULL like below?

jirka

> +
>  	for (i = 0; i < ARRAY_SIZE(test_symbols); i++) {
>  		if (test_symbols[i].id >= 0)
>  			continue;
> @@ -99,14 +121,20 @@ __resolve_symbol(struct btf *btf, int type_id)
>  		if (BTF_INFO_KIND(type->info) != test_symbols[i].type)
>  			continue;
>  
> -		str = btf__name_by_offset(btf, type->name_off);
> -		if (!ASSERT_OK_PTR(str, "btf__name_by_offset"))
> -			return -1;
> -
>  		if (!strcmp(str, test_symbols[i].name))
>  			test_symbols[i].id = type_id;
>  	}
>  

SNIP

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH bpf-next v1 0/4] Modernize resolve_btfids selftest
  2026-06-17 21:06 [PATCH bpf-next v1 0/4] Modernize resolve_btfids selftest Ihor Solodrai
                   ` (3 preceding siblings ...)
  2026-06-17 21:06 ` [PATCH bpf-next v1 4/4] selftests/bpf: Add kfunc set test to resolve_btfids Ihor Solodrai
@ 2026-06-18 12:32 ` Jiri Olsa
  4 siblings, 0 replies; 7+ messages in thread
From: Jiri Olsa @ 2026-06-18 12:32 UTC (permalink / raw)
  To: Ihor Solodrai
  Cc: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi, Alan Maguire,
	Emil Tsalapatis, bpf, linux-kbuild

On Wed, Jun 17, 2026 at 02:06:15PM -0700, Ihor Solodrai wrote:
> This series updates resolve_btfids selftests to use latest selftest
> helpers API and add kfunc set testing.
> 
> This series was split from a bigger series [1].  It's general selftest
> improvements that don't have to be entangled with resolve_btfids
> development, and makes the main series a bit smaller.
> 
> [1] https://lore.kernel.org/bpf/20260601221805.821394-1-ihor.solodrai@linux.dev/
> 
> Changes compared to original 4 patches:
>   * various nits from Jiri, Andrii and Emil
>   * in patch #3 (that adds gcc pragma) definitions are moved such that
>     .local BTF_ID_* containers are grouped together and we have a
>     single pragma scope

left one comment, otherwise lgtm

Acked-by: Jiri Olsa <jolsa@kernel.org>

jirka

> 
> ---
> 
> Ihor Solodrai (4):
>   tools/bpf: Sync btf_ids.h to tools
>   selftests/bpf: Modernize resolve_btfids test scaffolding
>   selftests/bpf: Fix resolve_btfids test reads of BTF ID sets in PIE
>     builds
>   selftests/bpf: Add kfunc set test to resolve_btfids
> 
>  tools/include/linux/btf_ids.h                 |  78 +++++++++-
>  .../selftests/bpf/prog_tests/resolve_btfids.c | 140 ++++++++++++------
>  tools/testing/selftests/bpf/progs/btf_data.c  |  10 ++
>  3 files changed, 177 insertions(+), 51 deletions(-)
> 
> -- 
> 2.54.0
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-06-18 12:32 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-17 21:06 [PATCH bpf-next v1 0/4] Modernize resolve_btfids selftest Ihor Solodrai
2026-06-17 21:06 ` [PATCH bpf-next v1 1/4] tools/bpf: Sync btf_ids.h to tools Ihor Solodrai
2026-06-17 21:06 ` [PATCH bpf-next v1 2/4] selftests/bpf: Modernize resolve_btfids test scaffolding Ihor Solodrai
2026-06-17 21:06 ` [PATCH bpf-next v1 3/4] selftests/bpf: Fix resolve_btfids test reads of BTF ID sets in PIE builds Ihor Solodrai
2026-06-17 21:06 ` [PATCH bpf-next v1 4/4] selftests/bpf: Add kfunc set test to resolve_btfids Ihor Solodrai
2026-06-18 12:31   ` Jiri Olsa
2026-06-18 12:32 ` [PATCH bpf-next v1 0/4] Modernize resolve_btfids selftest Jiri Olsa

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.