summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Leoshkevich <iii@linux.ibm.com>2025-10-17 11:19:07 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-10-19 16:34:05 +0200
commite1d6661095b0743e0d8387c99df114e6b1d06f49 (patch)
treef25b71e5cec7ce89e0cbd6d0e5d77482dfc8f261
parent9d04727414b7bc16a0da8a2dee8c4bc437a3a734 (diff)
downloadlinux-e1d6661095b0743e0d8387c99df114e6b1d06f49.tar.gz
linux-e1d6661095b0743e0d8387c99df114e6b1d06f49.tar.bz2
linux-e1d6661095b0743e0d8387c99df114e6b1d06f49.zip
s390/bpf: Write back tail call counter for BPF_TRAMP_F_CALL_ORIG
commit bc3905a71f02511607d3ccf732360580209cac4c upstream. The tailcall_bpf2bpf_hierarchy_fentry test hangs on s390. Its call graph is as follows: entry() subprog_tail() trampoline() fentry() the rest of subprog_tail() # via BPF_TRAMP_F_CALL_ORIG return to entry() The problem is that the rest of subprog_tail() increments the tail call counter, but the trampoline discards the incremented value. This results in an astronomically large number of tail calls. Fix by making the trampoline write the incremented tail call counter back. Fixes: 528eb2cb87bc ("s390/bpf: Implement arch_prepare_bpf_trampoline()") Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20250813121016.163375-4-iii@linux.ibm.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--arch/s390/net/bpf_jit_comp.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c
index 2526a3d53fad..f305cb42070d 100644
--- a/arch/s390/net/bpf_jit_comp.c
+++ b/arch/s390/net/bpf_jit_comp.c
@@ -2828,6 +2828,9 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
/* stg %r2,retval_off(%r15) */
EMIT6_DISP_LH(0xe3000000, 0x0024, REG_2, REG_0, REG_15,
tjit->retval_off);
+ /* mvc tccnt_off(%r15),tail_call_cnt(4,%r15) */
+ _EMIT6(0xd203f000 | tjit->tccnt_off,
+ 0xf000 | offsetof(struct prog_frame, tail_call_cnt));
im->ip_after_call = jit->prg_buf + jit->prg;