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. Signed-off-by: Ihor Solodrai --- .../selftests/bpf/prog_tests/resolve_btfids.c | 56 +++++++++++++++++++ tools/testing/selftests/bpf/progs/btf_data.c | 10 ++++ 2 files changed, 66 insertions(+) diff --git a/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c b/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c index d0e51979d455..f6fd79b9dd23 100644 --- a/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c +++ b/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c @@ -10,6 +10,10 @@ #include #include "test_progs.h" +#ifndef KF_FASTCALL +#define KF_FASTCALL (1 << 12) +#endif + struct symbol { const char *name; int type; @@ -26,6 +30,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" @@ -77,7 +92,13 @@ 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 + static int __resolve_symbol(struct btf *btf, int type_id) { @@ -108,6 +129,18 @@ __resolve_symbol(struct btf *btf, int type_id) test_symbols[i].id = type_id; } + if (BTF_INFO_KIND(type->info) == BTF_KIND_FUNC) { + str = btf__name_by_offset(btf, type->name_off); + if (str) { + 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; } @@ -162,6 +195,29 @@ 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++) { + bool found = false; + + for (j = 0; j < ARRAY_SIZE(kfunc_symbols); j++) { + if (kfunc_symbols[j].id != (s32)test_kfunc_set.pairs[i].id) + continue; + found = true; + ASSERT_EQ(test_kfunc_set.pairs[i].flags, + kfunc_symbols[j].flags, "kfunc_flags_check"); + break; + } + + ASSERT_TRUE(found, "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