[PATCH bpf-next v2 5/6] selftests/bpf: Test typeless module ksym resolution

From: Samuel Wu

Date: Thu Oct 22 2026 - 20:21:46 EST


Typeless module ksyms are resolved through kallsyms, but the existing
module ksym tests (ksyms_module, ksym_race) only use typed ksyms, which
are resolved through BTF. With KALLSYMS_QUERY, libbpf resolves module
symbols through the module lookup path of the ioctl.

Add a weak typeless extern for bpf_testmod_ksym_percpu to the ksyms test
and check that its address matches /proc/kallsyms when bpf_testmod is
loaded.

Signed-off-by: Samuel Wu <wusamuel@xxxxxxxxxx>
---
tools/testing/selftests/bpf/prog_tests/ksyms.c | 7 +++++++
tools/testing/selftests/bpf/progs/test_ksyms.c | 3 +++
2 files changed, 10 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/ksyms.c b/tools/testing/selftests/bpf/prog_tests/ksyms.c
index dc7aab532fb1..62760284f746 100644
--- a/tools/testing/selftests/bpf/prog_tests/ksyms.c
+++ b/tools/testing/selftests/bpf/prog_tests/ksyms.c
@@ -11,6 +11,7 @@ void test_ksyms(void)
struct test_ksyms *skel;
struct test_ksyms__data *data;
__u64 link_fops_addr, per_cpu_start_addr;
+ __u64 testmod_ksym_addr;
struct stat st;
__u64 btf_size;
int err;
@@ -48,6 +49,12 @@ void test_ksyms(void)
ASSERT_EQ(data->out__btf_size, btf_size, "btf_size");
ASSERT_EQ(data->out__per_cpu_start, per_cpu_start_addr, "__per_cpu_start");

+ if (env.has_testmod &&
+ ASSERT_OK(kallsyms_find("bpf_testmod_ksym_percpu", &testmod_ksym_addr),
+ "bpf_testmod_ksym_percpu: kallsyms_find"))
+ ASSERT_EQ(data->out__bpf_testmod_ksym, testmod_ksym_addr,
+ "bpf_testmod_ksym_percpu");
+
cleanup:
test_ksyms__destroy(skel);
}
diff --git a/tools/testing/selftests/bpf/progs/test_ksyms.c b/tools/testing/selftests/bpf/progs/test_ksyms.c
index 6c9cbb5a3bdf..69309f2a2d0a 100644
--- a/tools/testing/selftests/bpf/progs/test_ksyms.c
+++ b/tools/testing/selftests/bpf/progs/test_ksyms.c
@@ -9,6 +9,7 @@ __u64 out__bpf_link_fops = -1;
__u64 out__bpf_link_fops1 = -1;
__u64 out__btf_size = -1;
__u64 out__per_cpu_start = -1;
+__u64 out__bpf_testmod_ksym = -1;

extern const void bpf_link_fops __ksym;
extern const void __start_BTF __ksym;
@@ -16,6 +17,7 @@ extern const void __stop_BTF __ksym;
extern const void __per_cpu_start __ksym;
/* non-existing symbol, weak, default to zero */
extern const void bpf_link_fops1 __ksym __weak;
+extern const void bpf_testmod_ksym_percpu __ksym __weak;

SEC("raw_tp/sys_enter")
int handler(const void *ctx)
@@ -25,6 +27,7 @@ int handler(const void *ctx)
out__per_cpu_start = (__u64)&__per_cpu_start;

out__bpf_link_fops1 = (__u64)&bpf_link_fops1;
+ out__bpf_testmod_ksym = (__u64)&bpf_testmod_ksym_percpu;

return 0;
}
--
2.56.0.257.gf7497c7d27-goog