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

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Ilya Leoshkevich and committed by
Alexei Starovoitov
e4094d56 3733f4be

+15 -8
+15 -8
arch/s390/net/bpf_jit_comp.c
··· 1862 1862 jit->prg); 1863 1863 1864 1864 /* 1865 - * if (tail_call_cnt++ >= MAX_TAIL_CALL_CNT) 1865 + * if (tail_call_cnt >= MAX_TAIL_CALL_CNT) 1866 1866 * goto out; 1867 + * 1868 + * tail_call_cnt is read into %w0, which needs to be preserved 1869 + * until it's incremented and flushed. 1867 1870 */ 1868 1871 1869 1872 off = jit->frame_off + 1870 1873 offsetof(struct prog_frame, tail_call_cnt); 1871 - /* lhi %w0,1 */ 1872 - EMIT4_IMM(0xa7080000, REG_W0, 1); 1873 - /* laal %w1,%w0,off(%r15) */ 1874 - EMIT6_DISP_LH(0xeb000000, 0x00fa, REG_W1, REG_W0, REG_15, off); 1875 - /* clij %w1,MAX_TAIL_CALL_CNT-1,0x2,out */ 1874 + /* ly %w0,off(%r15) */ 1875 + EMIT6_DISP_LH(0xe3000000, 0x0058, REG_W0, REG_0, REG_15, off); 1876 + /* clij %w0,MAX_TAIL_CALL_CNT,0xa,out */ 1876 1877 patch_2_clij = jit->prg; 1877 - EMIT6_PCREL_RIEC(0xec000000, 0x007f, REG_W1, MAX_TAIL_CALL_CNT - 1, 1878 - 2, jit->prg); 1878 + EMIT6_PCREL_RIEC(0xec000000, 0x007f, REG_W0, MAX_TAIL_CALL_CNT, 1879 + 0xa, jit->prg); 1879 1880 1880 1881 /* 1881 1882 * prog = array->ptrs[index]; ··· 1894 1893 /* brc 0x8,out */ 1895 1894 patch_3_brc = jit->prg; 1896 1895 EMIT4_PCREL_RIC(0xa7040000, 8, jit->prg); 1896 + 1897 + /* tail_call_cnt++; */ 1898 + /* ahi %w0,1 */ 1899 + EMIT4_IMM(0xa70a0000, REG_W0, 1); 1900 + /* sty %w0,off(%r15) */ 1901 + EMIT6_DISP_LH(0xe3000000, 0x0050, REG_W0, REG_0, REG_15, off); 1897 1902 1898 1903 /* 1899 1904 * Restore registers before calling function