From 728ff167910ef16e97717719c749ddf4064c653b Mon Sep 17 00:00:00 2001 From: Emil Tsalapatis Date: Tue, 10 Feb 2026 13:45:32 -0500 Subject: libbpf: Add gating for arena globals relocation feature Add feature gating for the arena globals relocation introduced in commit c1f61171d44b. The commit depends on a previous commit in the same patchset that is absent from older kernels (12a1fe6e12db "bpf/verifier: Do not limit maximum direct offset into arena map"). Without this commit, arena globals relocation with arenas >= 512MiB fails to load and breaks libbpf's backwards compatibility. Introduce a libbpf feature to check whether the running kernel allows for full range ldimm64 offset, and only relocate arena globals if it does. Fixes: c1f61171d44b ("libbpf: Move arena globals to the end of the arena") Signed-off-by: Emil Tsalapatis Signed-off-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20260210184532.255475-1-emil@etsalapatis.com Signed-off-by: Alexei Starovoitov --- tools/lib/bpf/features.c | 64 +++++++++++++++++++++++++++++++++++++++++ tools/lib/bpf/libbpf.c | 7 +++-- tools/lib/bpf/libbpf_internal.h | 2 ++ 3 files changed, 71 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/lib/bpf/features.c b/tools/lib/bpf/features.c index b842b83e2480..b65ab109e3ff 100644 --- a/tools/lib/bpf/features.c +++ b/tools/lib/bpf/features.c @@ -506,6 +506,67 @@ static int probe_kern_arg_ctx_tag(int token_fd) return probe_fd(prog_fd); } +static int probe_ldimm64_full_range_off(int token_fd) +{ + char log_buf[1024]; + int prog_fd, map_fd; + int ret; + LIBBPF_OPTS(bpf_map_create_opts, map_opts, + .token_fd = token_fd, + .map_flags = token_fd ? BPF_F_TOKEN_FD : 0, + ); + LIBBPF_OPTS(bpf_prog_load_opts, prog_opts, + .token_fd = token_fd, + .prog_flags = token_fd ? BPF_F_TOKEN_FD : 0, + .log_buf = log_buf, + .log_size = sizeof(log_buf), + ); + struct bpf_insn insns[] = { + BPF_LD_MAP_VALUE(BPF_REG_1, 0, 1UL << 30), + BPF_EXIT_INSN(), + }; + int insn_cnt = ARRAY_SIZE(insns); + + map_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "arr", sizeof(int), 1, 1, &map_opts); + if (map_fd < 0) { + ret = -errno; + pr_warn("Error in %s(): %s. Couldn't create simple array map.\n", + __func__, errstr(ret)); + return ret; + } + insns[0].imm = map_fd; + + prog_fd = bpf_prog_load(BPF_PROG_TYPE_TRACEPOINT, "global_reloc", "GPL", insns, insn_cnt, &prog_opts); + ret = -errno; + + close(map_fd); + close(prog_fd); + + if (prog_fd >= 0) { + pr_warn("Error in %s(): Program loading unexpectedly succeeded.\n", __func__); + return -EINVAL; + } + + /* + * Feature is allowed if we're not failing with the error message + * "direct value offset of %u is not allowed" removed in + * 12a1fe6e12db ("bpf/verifier: Do not limit maximum direct offset into arena map"). + * We should instead fail with "invalid access to map value pointer". + * Ensure we match with one of the two and we're not failing with a + * different, unexpected message. + */ + if (strstr(log_buf, "direct value offset of")) + return 0; + + if (!strstr(log_buf, "invalid access to map value pointer")) { + pr_warn("Error in %s(): Program unexpectedly failed with message: %s.\n", + __func__, log_buf); + return ret; + } + + return 1; +} + typedef int (*feature_probe_fn)(int /* token_fd */); static struct kern_feature_cache feature_cache; @@ -581,6 +642,9 @@ static struct kern_feature_desc { [FEAT_BTF_QMARK_DATASEC] = { "BTF DATASEC names starting from '?'", probe_kern_btf_qmark_datasec, }, + [FEAT_LDIMM64_FULL_RANGE_OFF] = { + "full range LDIMM64 support", probe_ldimm64_full_range_off, + }, }; bool feat_supported(struct kern_feature_cache *cache, enum kern_feature_id feat_id) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 0c8bf0b5cce4..93e59ed8d9a1 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -3009,8 +3009,11 @@ static int init_arena_map_data(struct bpf_object *obj, struct bpf_map *map, memcpy(obj->arena_data, data, data_sz); obj->arena_data_sz = data_sz; - /* place globals at the end of the arena */ - obj->arena_data_off = mmap_sz - data_alloc_sz; + /* place globals at the end of the arena (if supported) */ + if (kernel_supports(obj, FEAT_LDIMM64_FULL_RANGE_OFF)) + obj->arena_data_off = mmap_sz - data_alloc_sz; + else + obj->arena_data_off = 0; /* make bpf_map__init_value() work for ARENA maps */ map->mmaped = obj->arena_data; diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h index fc59b21b51b5..974147e8a8aa 100644 --- a/tools/lib/bpf/libbpf_internal.h +++ b/tools/lib/bpf/libbpf_internal.h @@ -392,6 +392,8 @@ enum kern_feature_id { FEAT_ARG_CTX_TAG, /* Kernel supports '?' at the front of datasec names */ FEAT_BTF_QMARK_DATASEC, + /* Kernel supports LDIMM64 imm offsets past 512 MiB. */ + FEAT_LDIMM64_FULL_RANGE_OFF, __FEAT_CNT, }; -- cgit v1.2.3 From 04999b99e81eaa7b6223ec1c03af3bcb4ac57aaa Mon Sep 17 00:00:00 2001 From: Amery Hung Date: Mon, 9 Feb 2026 15:01:34 -0800 Subject: libbpf: Fix invalid write loop logic in bpf_linker__add_buf() Fix bpf_linker__add_buf()'s logic of copying data from memory buffer into memfd. In the event of short write not writing entire buf_sz bytes into memfd file, we'll append bytes from the beginning of buf *again* (corrupting ELF file contents) instead of correctly appending the rest of not-yet-read buf contents. Closes: https://github.com/libbpf/libbpf/issues/945 Fixes: 6d5e5e5d7ce1 ("libbpf: Extend linker API to support in-memory ELF files") Signed-off-by: Amery Hung Signed-off-by: Andrii Nakryiko Acked-by: Jiri Olsa Link: https://lore.kernel.org/bpf/20260209230134.3530521-1-ameryhung@gmail.com Signed-off-by: Alexei Starovoitov --- tools/lib/bpf/linker.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c index f4403e3cf994..78f92c39290a 100644 --- a/tools/lib/bpf/linker.c +++ b/tools/lib/bpf/linker.c @@ -581,7 +581,7 @@ int bpf_linker__add_buf(struct bpf_linker *linker, void *buf, size_t buf_sz, written = 0; while (written < buf_sz) { - ret = write(fd, buf, buf_sz); + ret = write(fd, buf + written, buf_sz - written); if (ret < 0) { ret = -errno; pr_warn("failed to write '%s': %s\n", filename, errstr(ret)); -- cgit v1.2.3 From 48f624c3dc71c2b807ce138bb70d1f5216532874 Mon Sep 17 00:00:00 2001 From: Ihor Solodrai Date: Tue, 10 Feb 2026 15:58:55 -0800 Subject: selftests/bpf: Adjust selftest due to function rename do_filp_open() was renamed in commit 541003b576c3 ("rename do_filp_open() to do_file_open()") This broke test_profiler, because it uses a kretprobe on that function. Fix it by renaming accordingly. Reported-by: Shung-Hsi Yu Closes: https://lore.kernel.org/bpf/djwjf2vfb7gro3rfag666bojod6ytcectahnb5z6hx2hawimtj@sx47ghzjg4lw/ Signed-off-by: Ihor Solodrai Link: https://lore.kernel.org/r/20260210235855.215679-1-ihor.solodrai@linux.dev Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/progs/profiler.h | 2 +- tools/testing/selftests/bpf/progs/profiler.inc.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/progs/profiler.h b/tools/testing/selftests/bpf/progs/profiler.h index 3bac4fdd4bdf..637fbf2c2652 100644 --- a/tools/testing/selftests/bpf/progs/profiler.h +++ b/tools/testing/selftests/bpf/progs/profiler.h @@ -169,7 +169,7 @@ enum bpf_function_id { profiler_bpf_sched_process_exec, profiler_bpf_sched_process_exit, profiler_bpf_sys_enter_kill, - profiler_bpf_do_filp_open_ret, + profiler_bpf_do_file_open_ret, profiler_bpf_sched_process_fork, profiler_bpf_vfs_link, profiler_bpf_vfs_symlink, diff --git a/tools/testing/selftests/bpf/progs/profiler.inc.h b/tools/testing/selftests/bpf/progs/profiler.inc.h index 813143b4985d..9044dd8aff11 100644 --- a/tools/testing/selftests/bpf/progs/profiler.inc.h +++ b/tools/testing/selftests/bpf/progs/profiler.inc.h @@ -751,11 +751,11 @@ out: return 0; } -SEC("kretprobe/do_filp_open") -int kprobe_ret__do_filp_open(struct pt_regs* ctx) +SEC("kretprobe/do_file_open") +int kprobe_ret__do_file_open(struct pt_regs *ctx) { struct bpf_func_stats_ctx stats_ctx; - bpf_stats_enter(&stats_ctx, profiler_bpf_do_filp_open_ret); + bpf_stats_enter(&stats_ctx, profiler_bpf_do_file_open_ret); struct file* filp = (struct file*)PT_REGS_RC_CORE(ctx); -- cgit v1.2.3 From 2669dde7a8c67e3efe8052d75d6040de2cbb5e5a Mon Sep 17 00:00:00 2001 From: Kumar Kartikeya Dwivedi Date: Wed, 11 Feb 2026 10:57:47 -0800 Subject: selftests/bpf: Fix map_kptr grace period wait Commit c27cea4416a3 ("rcu: Re-implement RCU Tasks Trace in terms of SRCU-fast") broke map_kptr selftest since it removed the function we were kprobing. Use a new kfunc that invokes call_rcu_tasks_trace and sets a program provided pointer to an integer to 1. Technically this can be unsafe if the memory being written to from the callback disappears, but this is just for usage in a test where we ensure we spin until we see the value to be set to 1, so it's ok. Reported-by: Shung-Hsi Yu Fixes: c27cea4416a3 ("rcu: Re-implement RCU Tasks Trace in terms of SRCU-fast") Signed-off-by: Kumar Kartikeya Dwivedi Link: https://lore.kernel.org/r/20260211185747.3630539-1-memxor@gmail.com Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/prog_tests/map_kptr.c | 15 +++++------ .../selftests/bpf/progs/rcu_tasks_trace_gp.c | 30 +++------------------- .../testing/selftests/bpf/test_kmods/bpf_testmod.c | 28 ++++++++++++++++++++ .../selftests/bpf/test_kmods/bpf_testmod_kfunc.h | 1 + 4 files changed, 39 insertions(+), 35 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/map_kptr.c b/tools/testing/selftests/bpf/prog_tests/map_kptr.c index f372162c0280..03b46f17cf53 100644 --- a/tools/testing/selftests/bpf/prog_tests/map_kptr.c +++ b/tools/testing/selftests/bpf/prog_tests/map_kptr.c @@ -118,15 +118,16 @@ exit: static int kern_sync_rcu_tasks_trace(struct rcu_tasks_trace_gp *rcu) { - long gp_seq = READ_ONCE(rcu->bss->gp_seq); LIBBPF_OPTS(bpf_test_run_opts, opts); + int ret; - if (!ASSERT_OK(bpf_prog_test_run_opts(bpf_program__fd(rcu->progs.do_call_rcu_tasks_trace), - &opts), "do_call_rcu_tasks_trace")) + WRITE_ONCE(rcu->bss->done, 0); + ret = bpf_prog_test_run_opts(bpf_program__fd(rcu->progs.call_rcu_tasks_trace), &opts); + if (!ASSERT_OK(ret, "call_rcu_tasks_trace")) return -EFAULT; - if (!ASSERT_OK(opts.retval, "opts.retval == 0")) + if (!ASSERT_OK(opts.retval, "call_rcu_tasks_trace retval")) return -EFAULT; - while (gp_seq == READ_ONCE(rcu->bss->gp_seq)) + while (!READ_ONCE(rcu->bss->done)) sched_yield(); return 0; } @@ -159,8 +160,6 @@ void serial_test_map_kptr(void) skel = rcu_tasks_trace_gp__open_and_load(); if (!ASSERT_OK_PTR(skel, "rcu_tasks_trace_gp__open_and_load")) return; - if (!ASSERT_OK(rcu_tasks_trace_gp__attach(skel), "rcu_tasks_trace_gp__attach")) - goto end; if (test__start_subtest("success-map")) { test_map_kptr_success(true); @@ -180,7 +179,5 @@ void serial_test_map_kptr(void) test_map_kptr_success(true); } -end: rcu_tasks_trace_gp__destroy(skel); - return; } diff --git a/tools/testing/selftests/bpf/progs/rcu_tasks_trace_gp.c b/tools/testing/selftests/bpf/progs/rcu_tasks_trace_gp.c index df4873558634..189c05c6abcc 100644 --- a/tools/testing/selftests/bpf/progs/rcu_tasks_trace_gp.c +++ b/tools/testing/selftests/bpf/progs/rcu_tasks_trace_gp.c @@ -1,36 +1,14 @@ // SPDX-License-Identifier: GPL-2.0 #include -#include #include +#include "../test_kmods/bpf_testmod_kfunc.h" -struct task_ls_map { - __uint(type, BPF_MAP_TYPE_TASK_STORAGE); - __uint(map_flags, BPF_F_NO_PREALLOC); - __type(key, int); - __type(value, int); -} task_ls_map SEC(".maps"); - -long gp_seq; +int done; SEC("syscall") -int do_call_rcu_tasks_trace(void *ctx) -{ - struct task_struct *current; - int *v; - - current = bpf_get_current_task_btf(); - v = bpf_task_storage_get(&task_ls_map, current, NULL, BPF_LOCAL_STORAGE_GET_F_CREATE); - if (!v) - return 1; - /* Invoke call_rcu_tasks_trace */ - return bpf_task_storage_delete(&task_ls_map, current); -} - -SEC("kprobe/rcu_tasks_trace_postgp") -int rcu_tasks_trace_postgp(void *ctx) +int call_rcu_tasks_trace(void *ctx) { - __sync_add_and_fetch(&gp_seq, 1); - return 0; + return bpf_kfunc_call_test_call_rcu_tasks_trace(&done); } char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c index 186a25ab429a..e62c6b78657f 100644 --- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c +++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include "bpf_testmod.h" @@ -885,6 +886,32 @@ __bpf_kfunc void bpf_kfunc_call_test_sleepable(void) { } +struct bpf_kfunc_rcu_tasks_trace_data { + struct rcu_head rcu; + int *done; +}; + +static void bpf_kfunc_rcu_tasks_trace_cb(struct rcu_head *rhp) +{ + struct bpf_kfunc_rcu_tasks_trace_data *data; + + data = container_of(rhp, struct bpf_kfunc_rcu_tasks_trace_data, rcu); + WRITE_ONCE(*data->done, 1); + kfree(data); +} + +__bpf_kfunc int bpf_kfunc_call_test_call_rcu_tasks_trace(int *done) +{ + struct bpf_kfunc_rcu_tasks_trace_data *data; + + data = kmalloc(sizeof(*data), GFP_ATOMIC); + if (!data) + return -ENOMEM; + data->done = done; + call_rcu_tasks_trace(&data->rcu, bpf_kfunc_rcu_tasks_trace_cb); + return 0; +} + __bpf_kfunc int bpf_kfunc_init_sock(struct init_sock_args *args) { int proto; @@ -1222,6 +1249,7 @@ BTF_ID_FLAGS(func, bpf_kfunc_call_test_destructive, KF_DESTRUCTIVE) BTF_ID_FLAGS(func, bpf_kfunc_call_test_static_unused_arg) BTF_ID_FLAGS(func, bpf_kfunc_call_test_offset) BTF_ID_FLAGS(func, bpf_kfunc_call_test_sleepable, KF_SLEEPABLE) +BTF_ID_FLAGS(func, bpf_kfunc_call_test_call_rcu_tasks_trace) BTF_ID_FLAGS(func, bpf_kfunc_init_sock, KF_SLEEPABLE) BTF_ID_FLAGS(func, bpf_kfunc_close_sock, KF_SLEEPABLE) BTF_ID_FLAGS(func, bpf_kfunc_call_kernel_connect, KF_SLEEPABLE) diff --git a/tools/testing/selftests/bpf/test_kmods/bpf_testmod_kfunc.h b/tools/testing/selftests/bpf/test_kmods/bpf_testmod_kfunc.h index d5c5454e257e..b393bf771131 100644 --- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod_kfunc.h +++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod_kfunc.h @@ -118,6 +118,7 @@ void bpf_kfunc_call_test_mem_len_fail2(__u64 *mem, int len) __ksym; void bpf_kfunc_call_test_destructive(void) __ksym; void bpf_kfunc_call_test_sleepable(void) __ksym; +int bpf_kfunc_call_test_call_rcu_tasks_trace(int *done) __ksym; void bpf_kfunc_call_test_offset(struct prog_test_ref_kfunc *p); struct prog_test_member *bpf_kfunc_call_memb_acquire(void); -- cgit v1.2.3 From 0265c1fd912ee0ea0cb00c539fb73e99578a866d Mon Sep 17 00:00:00 2001 From: Menglong Dong Date: Sun, 8 Feb 2026 13:33:11 +0800 Subject: selftests/bpf: enable fsession_test on riscv64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that the RISC-V trampoline JIT supports BPF_TRACE_FSESSION, run the fsession selftest on riscv64 as well as x86_64. Signed-off-by: Menglong Dong Tested-by: Björn Töpel Acked-by: Björn Töpel Link: https://lore.kernel.org/r/20260208053311.698352-4-dongml2@chinatelecom.cn Signed-off-by: Alexei Starovoitov Reviewed-by: Pu Lehui Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/progs/get_func_args_test.c | 2 +- tools/testing/selftests/bpf/progs/get_func_ip_test.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/progs/get_func_args_test.c b/tools/testing/selftests/bpf/progs/get_func_args_test.c index 180ba5098ca1..075a1180ec26 100644 --- a/tools/testing/selftests/bpf/progs/get_func_args_test.c +++ b/tools/testing/selftests/bpf/progs/get_func_args_test.c @@ -167,7 +167,7 @@ int BPF_PROG(tp_test2) } __u64 test7_result = 0; -#if defined(bpf_target_x86) || defined(bpf_target_arm64) +#if defined(bpf_target_x86) || defined(bpf_target_arm64) || defined(bpf_target_riscv) SEC("fsession/bpf_fentry_test1") int BPF_PROG(test7) { diff --git a/tools/testing/selftests/bpf/progs/get_func_ip_test.c b/tools/testing/selftests/bpf/progs/get_func_ip_test.c index 43ff836a8ed8..45eaa54d1ac7 100644 --- a/tools/testing/selftests/bpf/progs/get_func_ip_test.c +++ b/tools/testing/selftests/bpf/progs/get_func_ip_test.c @@ -106,7 +106,7 @@ int BPF_URETPROBE(test8, int ret) __u64 test9_entry_result = 0; __u64 test9_exit_result = 0; -#if defined(bpf_target_x86) || defined(bpf_target_arm64) +#if defined(bpf_target_x86) || defined(bpf_target_arm64) || defined(bpf_target_riscv) SEC("fsession/bpf_fentry_test1") int BPF_PROG(test9, int a) { -- cgit v1.2.3 From 7cefbb47ccb2ded187f72db17a46f19d7cf4bf08 Mon Sep 17 00:00:00 2001 From: Emil Tsalapatis Date: Tue, 17 Feb 2026 15:43:44 -0500 Subject: libbpf: Do not use PROG_TYPE_TRACEPOINT program for feature gating Commit 728ff167910e uses a PROG_TYPE_TRACEPOINT BPF test program to check whether the running kernel supports large LDIMM64 offsets. The feature gate incorrectly assumes that the program will fail at verification time with one of two messages, depending on whether the feature is supported by the running kernel. However, PROG_TYPE_TRACEPOINT programs may fail to load before verification even starts, e.g., if the shell does not have the appropriate capabilities. Use a BPF_PROG_TYPE_SOCKET_FILTER program for the feature gate instead. Also fix two minor issues. First, ensure the log buffer for the test is initialized: Failing program load before verification led to libbpf dumping uninitialized data to stdout. Also, ensure that close() is only called for program_fd in the probe if the program load actually succeeded. The call was currently failing silently with -EBADF most of the time. Fixes: 728ff167910e ("libbpf: Add gating for arena globals relocation feature") Reported-by: Alexei Starovoitov Signed-off-by: Emil Tsalapatis Signed-off-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20260217204345.548648-2-emil@etsalapatis.com --- tools/lib/bpf/features.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/lib/bpf/features.c b/tools/lib/bpf/features.c index b65ab109e3ff..2fa434f09cce 100644 --- a/tools/lib/bpf/features.c +++ b/tools/lib/bpf/features.c @@ -536,14 +536,15 @@ static int probe_ldimm64_full_range_off(int token_fd) } insns[0].imm = map_fd; - prog_fd = bpf_prog_load(BPF_PROG_TYPE_TRACEPOINT, "global_reloc", "GPL", insns, insn_cnt, &prog_opts); + log_buf[0] = '\0'; + prog_fd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, "global_reloc", "GPL", insns, insn_cnt, &prog_opts); ret = -errno; close(map_fd); - close(prog_fd); if (prog_fd >= 0) { pr_warn("Error in %s(): Program loading unexpectedly succeeded.\n", __func__); + close(prog_fd); return -EINVAL; } -- cgit v1.2.3 From d7988720ef3ea5926f1b886b27eddf08abbadba0 Mon Sep 17 00:00:00 2001 From: Emil Tsalapatis Date: Tue, 17 Feb 2026 15:43:45 -0500 Subject: libbpf: Delay feature gate check until object prepare time Commit 728ff167910e ("libbpf: Add gating for arena globals relocation feature") adds a feature gate check that loads a map and BPF program to test the running kernel supports large direct offsets for LDIMM64 instructions. This check is currently used to calculate arena symbol offsets during bpf_object__collect_relos, itself called by bpf_object_open. However, the program calling bpf_object_open may not have the permissions to load maps and programs. This is the case with the BPF selftests, where bpftool is invoked at compilation time during skeleton generation. This causes errors as the feature gate unexpectedly fails with -EPERM. Avoid this by moving all the use of the FEAT_LDIMM64_FULL_RANGE_OFF feature gate to BPF object preparation time instead. Fixes: 728ff167910e ("libbpf: Add gating for arena globals relocation feature") Signed-off-by: Emil Tsalapatis Signed-off-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20260217204345.548648-3-emil@etsalapatis.com --- tools/lib/bpf/libbpf.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 93e59ed8d9a1..0be7017800fe 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -3009,12 +3009,6 @@ static int init_arena_map_data(struct bpf_object *obj, struct bpf_map *map, memcpy(obj->arena_data, data, data_sz); obj->arena_data_sz = data_sz; - /* place globals at the end of the arena (if supported) */ - if (kernel_supports(obj, FEAT_LDIMM64_FULL_RANGE_OFF)) - obj->arena_data_off = mmap_sz - data_alloc_sz; - else - obj->arena_data_off = 0; - /* make bpf_map__init_value() work for ARENA maps */ map->mmaped = obj->arena_data; @@ -4672,7 +4666,7 @@ static int bpf_program__record_reloc(struct bpf_program *prog, reloc_desc->type = RELO_DATA; reloc_desc->insn_idx = insn_idx; reloc_desc->map_idx = obj->arena_map_idx; - reloc_desc->sym_off = sym->st_value + obj->arena_data_off; + reloc_desc->sym_off = sym->st_value; map = &obj->maps[obj->arena_map_idx]; pr_debug("prog '%s': found arena map %d (%s, sec %d, off %zu) for insn %u\n", @@ -6386,6 +6380,10 @@ bpf_object__relocate_data(struct bpf_object *obj, struct bpf_program *prog) case RELO_DATA: map = &obj->maps[relo->map_idx]; insn[1].imm = insn[0].imm + relo->sym_off; + + if (relo->map_idx == obj->arena_map_idx) + insn[1].imm += obj->arena_data_off; + if (obj->gen_loader) { insn[0].src_reg = BPF_PSEUDO_MAP_IDX_VALUE; insn[0].imm = relo->map_idx; @@ -7387,6 +7385,14 @@ static int bpf_object__relocate(struct bpf_object *obj, const char *targ_btf_pat bpf_object__sort_relos(obj); } + /* place globals at the end of the arena (if supported) */ + if (obj->arena_map_idx >= 0 && kernel_supports(obj, FEAT_LDIMM64_FULL_RANGE_OFF)) { + struct bpf_map *arena_map = &obj->maps[obj->arena_map_idx]; + + obj->arena_data_off = bpf_map_mmap_sz(arena_map) - + roundup(obj->arena_data_sz, sysconf(_SC_PAGE_SIZE)); + } + /* Before relocating calls pre-process relocations and mark * few ld_imm64 instructions that points to subprogs. * Otherwise bpf_object__reloc_code() later would have to consider -- cgit v1.2.3 From 3b39d73cc3379360a33eb583b17f21fe55e1288e Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Tue, 17 Feb 2026 11:41:50 -0800 Subject: bpftool: Fix truncated netlink dumps Netlink requires that the recv buffer used during dumps is at least min(PAGE_SIZE, 8k) (see the man page). Otherwise the messages will get truncated. Make sure bpftool follows this requirement, avoid missing information on systems with large pages. Acked-by: Quentin Monnet Fixes: 7084566a236f ("tools/bpftool: Remove libbpf_internal.h usage in bpftool") Signed-off-by: Jakub Kicinski Link: https://lore.kernel.org/r/20260217194150.734701-1-kuba@kernel.org Signed-off-by: Alexei Starovoitov --- tools/bpf/bpftool/net.c | 5 ++++- tools/lib/bpf/netlink.c | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c index f25d66c8395e..974189da8a91 100644 --- a/tools/bpf/bpftool/net.c +++ b/tools/bpf/bpftool/net.c @@ -156,7 +156,7 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq, bool multipart = true; struct nlmsgerr *err; struct nlmsghdr *nh; - char buf[4096]; + char buf[8192]; int len, ret; while (multipart) { @@ -201,6 +201,9 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq, return ret; } } + + if (len) + p_err("Invalid message or trailing data in Netlink response: %d bytes left", len); } ret = 0; done: diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c index c997e69d507f..c9a78fb16f11 100644 --- a/tools/lib/bpf/netlink.c +++ b/tools/lib/bpf/netlink.c @@ -143,7 +143,7 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq, struct nlmsghdr *nh; int len, ret; - ret = alloc_iov(&iov, 4096); + ret = alloc_iov(&iov, 8192); if (ret) goto done; @@ -212,6 +212,8 @@ start: } } } + if (len) + pr_warn("Invalid message or trailing data in Netlink response: %d bytes left\n", len); } ret = 0; done: -- cgit v1.2.3 From b3dfa128f7da7c4dd371a4aff685cd249604e029 Mon Sep 17 00:00:00 2001 From: Ihor Solodrai Date: Wed, 18 Feb 2026 13:56:50 -0800 Subject: selftests/bpf: Use vmlinux.h in test_xdp_meta - Replace linux/* includes with vmlinux.h - Include errno.h - Include bpf_tracing_net.h for TC_ACT_* and ETH_* - Use BPF_STDERR instead of BPF_STREAM_STDERR Signed-off-by: Ihor Solodrai Link: https://lore.kernel.org/r/20260218215651.2057673-2-ihor.solodrai@linux.dev Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/progs/test_xdp_meta.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/progs/test_xdp_meta.c b/tools/testing/selftests/bpf/progs/test_xdp_meta.c index 0a0f371a2dec..fa73b17cb999 100644 --- a/tools/testing/selftests/bpf/progs/test_xdp_meta.c +++ b/tools/testing/selftests/bpf/progs/test_xdp_meta.c @@ -1,12 +1,12 @@ -#include -#include -#include -#include -#include +// SPDX-License-Identifier: GPL-2.0 +#include #include #include +#include + #include "bpf_kfuncs.h" +#include "bpf_tracing_net.h" #define META_SIZE 32 @@ -42,7 +42,7 @@ static bool check_metadata(const char *file, int line, __u8 *meta_have) if (!__builtin_memcmp(meta_have, meta_want, META_SIZE)) return true; - bpf_stream_printk(BPF_STREAM_STDERR, + bpf_stream_printk(BPF_STDERR, "FAIL:%s:%d: metadata mismatch\n" " have:\n %pI6\n %pI6\n" " want:\n %pI6\n %pI6\n", -- cgit v1.2.3 From 0cecd492f5165d3e7a314b87e9b7787734eab324 Mon Sep 17 00:00:00 2001 From: Ihor Solodrai Date: Wed, 18 Feb 2026 13:56:51 -0800 Subject: libbpf: Remove extern declaration of bpf_stream_vprintk() An issue was reported that building BPF program which includes both vmlinux.h and bpf_helpers.h from libbpf fails due to conflicting declarations of bpf_stream_vprintk(). Remove the extern declaration from bpf_helpers.h to address this. In order to use bpf_stream_printk() macro, BPF programs are expected to either include vmlinux.h of the kernel they are targeting, or add their own extern declaration. Reported-by: Luca Boccassi Closes: https://github.com/libbpf/libbpf/issues/947 Signed-off-by: Ihor Solodrai Link: https://lore.kernel.org/r/20260218215651.2057673-3-ihor.solodrai@linux.dev Signed-off-by: Alexei Starovoitov --- tools/lib/bpf/bpf_helpers.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'tools') diff --git a/tools/lib/bpf/bpf_helpers.h b/tools/lib/bpf/bpf_helpers.h index c145da05a67c..9d160b5b9c0e 100644 --- a/tools/lib/bpf/bpf_helpers.h +++ b/tools/lib/bpf/bpf_helpers.h @@ -315,9 +315,6 @@ enum libbpf_tristate { ___param, sizeof(___param)); \ }) -extern int bpf_stream_vprintk(int stream_id, const char *fmt__str, const void *args, - __u32 len__sz) __weak __ksym; - #define bpf_stream_printk(stream_id, fmt, args...) \ ({ \ static const char ___fmt[] = fmt; \ -- cgit v1.2.3 From 1e5c009126952f673ffa2427acbd69e57493f0d2 Mon Sep 17 00:00:00 2001 From: "Matthieu Baerts (NGI0)" Date: Wed, 18 Feb 2026 13:01:44 +0100 Subject: selftests/bpf: Remove hexdump dependency The verification signature header generation requires converting a binary certificate to a C array. Previously this only worked with xxd, and a switch to hexdump has been done in commit b640d556a2b3 ("selftests/bpf: Remove xxd util dependency"). hexdump is a more common utility program, yet it might not be installed by default. When it is not installed, BPF selftests build without errors, but tests_progs is unusable: it exits with the 255 code and without any error messages. When manually reproducing the issue, it is not too hard to find out that the generated verification_cert.h file is incorrect, but that's time consuming. When digging the BPF selftests build logs, this line can be seen amongst thousands others, but ignored: /bin/sh: 2: hexdump: not found Here, od is used instead of hexdump. od is coming from the coreutils package, and this new od command produces the same output when using od from GNU coreutils, uutils, and even busybox. This is more portable, and it produces a similar results to what was done before with hexdump: there is an extra comma at the end instead of trailing whitespaces, but the C code is not impacted. Fixes: b640d556a2b3 ("selftests/bpf: Remove xxd util dependency") Signed-off-by: Matthieu Baerts (NGI0) Tested-by: Alan Maguire Link: https://lore.kernel.org/r/20260218-bpf-sft-hexdump-od-v2-1-2f9b3ee5ab86@kernel.org Signed-off-by: Alexei Starovoitov --- tools/testing/selftests/bpf/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index c6bf4dfb1495..6776158f1f3e 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -723,7 +723,7 @@ $(VERIFICATION_CERT) $(PRIVATE_KEY): $(VERIFY_SIG_SETUP) # Generates a header with C array declaration, containing test_progs_verification_cert bytes $(VERIFY_SIG_HDR): $(VERIFICATION_CERT) $(Q)(echo "unsigned char test_progs_verification_cert[] = {"; \ - hexdump -v -e '12/1 " 0x%02x," "\n"' $< | sed 's/0x ,//g; $$s/,$$//'; \ + od -v -t 'xC' -w12 $< | sed 's/ \(\S\+\)/ 0x\1,/g;s/^\S\+/ /;$$d'; \ echo "};"; \ echo "unsigned int test_progs_verification_cert_len = $$(wc -c < $<);") > $@ -- cgit v1.2.3