Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/bpf: Write back tail call counter for BPF_TRAMP_F_CALL_ORIG

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

authored by

Ilya Leoshkevich and committed by
Daniel Borkmann
bc3905a7 c861a6b1

+3
+3
arch/s390/net/bpf_jit_comp.c
··· 2839 2839 /* stg %r2,retval_off(%r15) */ 2840 2840 EMIT6_DISP_LH(0xe3000000, 0x0024, REG_2, REG_0, REG_15, 2841 2841 tjit->retval_off); 2842 + /* mvc tccnt_off(%r15),tail_call_cnt(4,%r15) */ 2843 + _EMIT6(0xd203f000 | tjit->tccnt_off, 2844 + 0xf000 | offsetof(struct prog_frame, tail_call_cnt)); 2842 2845 2843 2846 im->ip_after_call = jit->prg_buf + jit->prg; 2844 2847