From: Yonghong Song <yonghong.song@linux.dev>
To: bpf@vger.kernel.org
Cc: Alexei Starovoitov <ast@kernel.org>,
Andrii Nakryiko <andrii@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Eduard Zingerman <eddyz87@gmail.com>,
kernel-team@fb.com
Subject: [PATCH bpf-next] selftests/bpf: Fix callback recursion test with noipa global func
Date: Mon, 2 Nov 2026 11:27:27 -0800 [thread overview]
Message-ID: <20261102192727.762933-1-yonghong.song@linux.dev> (raw)
With llvm24 after commit 28b4a2032f97 ("[BPF] Mark global functions
noipa"), the test recursion_via_global_func_and_callback fails:
13: (85) call bpf_loop#181 4: frame1: R1=scalar() R10=fp0 cb
; return static_calls_global(i); @ verifier_global_subprogs.c:548
4: (85) call pc+1
...
; return global_calls_loop(x); @ verifier_global_subprogs.c:543
6: (85) call pc+1
Func#3 ('global_calls_loop') is global and assumed valid.
7: frame2: R0=scalar()
7: (95) exit
...
; return static_calls_global(i); @ verifier_global_subprogs.c:548
5: (95) exit
At callback return the register R0 has unknown scalar value should have been in [0, 1]
=============
EXPECTED SUBSTR: 'recursive call from global_calls_loop() to loop_cb_calls_static()'
#669/9 verifier_global_subprogs/recursion_via_global_func_and_callback:FAIL
The callback loop_cb_calls_static() returns the result of
static_calls_global(), which in turn returns the result of the global
function global_calls_loop().
Before the above llvm24 commit, IPSCCP (interprocedural sparse
conditional constant propagation) could fold the return value of
global_calls_loop() into its callers. global_calls_loop() is not
static, but it has a non-weak definition in the same compilation unit,
so IPSCCP may assume that definition is the one called. It found that
global_calls_loop() always returns 0 and replaced the uses of the call
result with 0, which made static_calls_global() and then
loop_cb_calls_static() return a constant 0 as well. The calls stay, only
their return values are replaced. So the callback set R0 to 0 itself,
passed the bpf_loop callback return range check, and verification went
on to report the expected recursion.
The llvm24 commit marks global functions noipa, since the verifier
checks a global function only against its BTF prototype and freplace
can replace it. With noipa, IPSCCP no longer propagates the return
value of global_calls_loop() to callers. The verifier does not look
into a global function either, so R0 after the call is an unknown
scalar, and the callback return check fails before the recursion is
detected.
Make static_calls_global() return void and let loop_cb_calls_static()
return 0 explicitly. The call chain the test is about stays the same,
and the test passes with both llvm24 and earlier versions (e.g. llvm21
to llvm23).
Link: https://github.com/llvm/llvm-project/pull/237690
Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
---
.../testing/selftests/bpf/progs/verifier_global_subprogs.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/bpf/progs/verifier_global_subprogs.c b/tools/testing/selftests/bpf/progs/verifier_global_subprogs.c
index 574b26b5a7df..5e8461b2167d 100644
--- a/tools/testing/selftests/bpf/progs/verifier_global_subprogs.c
+++ b/tools/testing/selftests/bpf/progs/verifier_global_subprogs.c
@@ -538,14 +538,15 @@ int return_from_void_global(struct __sk_buff *skb)
int global_calls_loop(int x);
-static __noinline int static_calls_global(int x)
+static __noinline void static_calls_global(int x)
{
- return global_calls_loop(x);
+ global_calls_loop(x);
}
static __noinline int loop_cb_calls_static(u32 i, void *ctx)
{
- return static_calls_global(i);
+ static_calls_global(i);
+ return 0;
}
__noinline int global_calls_loop(int x)
--
2.53.0-Meta
next reply other threads:[~2026-11-02 19:27 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-02 19:27 Yonghong Song [this message]
2026-11-02 22:50 ` [PATCH bpf-next] selftests/bpf: Fix callback recursion test with noipa global func patchwork-bot+netdevbpf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261102192727.762933-1-yonghong.song@linux.dev \
--to=yonghong.song@linux.dev \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=kernel-team@fb.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.