Skip to content

Commit c861a6b

Browse files
iii-iborkmann
authored andcommitted
s390/bpf: Write back tail call counter for BPF_PSEUDO_CALL
The tailcall_bpf2bpf_hierarchy_1 test hangs on s390. Its call graph is as follows: entry() subprog_tail() bpf_tail_call_static(0) -> entry + tail_call_start subprog_tail() bpf_tail_call_static(0) -> entry + tail_call_start entry() copies its tail call counter to the subprog_tail()'s frame, which then increments it. However, the incremented result is discarded, leading to an astronomically large number of tail calls. Fix by writing the incremented counter back to the entry()'s frame. Fixes: dd691e8 ("s390/bpf: Implement bpf_jit_supports_subprog_tailcalls()") Signed-off-by: Ilya Leoshkevich <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent eada40e commit c861a6b

File tree

1 file changed

+16
-7
lines changed

1 file changed

+16
-7
lines changed

arch/s390/net/bpf_jit_comp.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,13 +1793,6 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
17931793

17941794
/*
17951795
* Copy the tail call counter to where the callee expects it.
1796-
*
1797-
* Note 1: The callee can increment the tail call counter, but
1798-
* we do not load it back, since the x86 JIT does not do this
1799-
* either.
1800-
*
1801-
* Note 2: We assume that the verifier does not let us call the
1802-
* main program, which clears the tail call counter on entry.
18031796
*/
18041797

18051798
if (insn->src_reg == BPF_PSEUDO_CALL)
@@ -1833,6 +1826,22 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
18331826
call_r1(jit);
18341827
/* lgr %b0,%r2: load return value into %b0 */
18351828
EMIT4(0xb9040000, BPF_REG_0, REG_2);
1829+
1830+
/*
1831+
* Copy the potentially updated tail call counter back.
1832+
*/
1833+
1834+
if (insn->src_reg == BPF_PSEUDO_CALL)
1835+
/*
1836+
* mvc frame_off+tail_call_cnt(%r15),
1837+
* tail_call_cnt(4,%r15)
1838+
*/
1839+
_EMIT6(0xd203f000 | (jit->frame_off +
1840+
offsetof(struct prog_frame,
1841+
tail_call_cnt)),
1842+
0xf000 | offsetof(struct prog_frame,
1843+
tail_call_cnt));
1844+
18361845
break;
18371846
}
18381847
case BPF_JMP | BPF_TAIL_CALL: {

0 commit comments

Comments
 (0)