s390/bpf: Do not increment tailcall count when prog is NULL

Currently tail calling a non-existent prog results in tailcall count
increment. This is what the interpreter is doing, but this is clearly
wrong, so replace load-and-increment and compare-and-jump with load
and compare-and-jump, conditionally followed by increment and store.

Reported-by: Hari Bathini <hbathini@linux.ibm.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Link: https://lore.kernel.org/r/20260217161058.101346-1-iii@linux.ibm.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
Ilya Leoshkevich 2026-02-17 17:10:06 +01:00 committed by Alexei Starovoitov
parent 3733f4be28
commit e4094d56c5

View File

@ -1862,20 +1862,21 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
jit->prg);
/*
* if (tail_call_cnt++ >= MAX_TAIL_CALL_CNT)
* if (tail_call_cnt >= MAX_TAIL_CALL_CNT)
* goto out;
*
* tail_call_cnt is read into %w0, which needs to be preserved
* until it's incremented and flushed.
*/
off = jit->frame_off +
offsetof(struct prog_frame, tail_call_cnt);
/* lhi %w0,1 */
EMIT4_IMM(0xa7080000, REG_W0, 1);
/* laal %w1,%w0,off(%r15) */
EMIT6_DISP_LH(0xeb000000, 0x00fa, REG_W1, REG_W0, REG_15, off);
/* clij %w1,MAX_TAIL_CALL_CNT-1,0x2,out */
/* ly %w0,off(%r15) */
EMIT6_DISP_LH(0xe3000000, 0x0058, REG_W0, REG_0, REG_15, off);
/* clij %w0,MAX_TAIL_CALL_CNT,0xa,out */
patch_2_clij = jit->prg;
EMIT6_PCREL_RIEC(0xec000000, 0x007f, REG_W1, MAX_TAIL_CALL_CNT - 1,
2, jit->prg);
EMIT6_PCREL_RIEC(0xec000000, 0x007f, REG_W0, MAX_TAIL_CALL_CNT,
0xa, jit->prg);
/*
* prog = array->ptrs[index];
@ -1894,6 +1895,12 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
patch_3_brc = jit->prg;
EMIT4_PCREL_RIC(0xa7040000, 8, jit->prg);
/* tail_call_cnt++; */
/* ahi %w0,1 */
EMIT4_IMM(0xa70a0000, REG_W0, 1);
/* sty %w0,off(%r15) */
EMIT6_DISP_LH(0xe3000000, 0x0050, REG_W0, REG_0, REG_15, off);
/*
* Restore registers before calling function
*/