Message ID | 20190812161807.1400-1-iii@linux.ibm.com |
---|---|
State | Accepted |
Delegated to: | BPF Maintainers |
Headers | show |
Series | [bpf] s390/bpf: use 32-bit index for tail calls | expand |
On 8/12/19 6:18 PM, Ilya Leoshkevich wrote: > "p runtime/jit: pass > 32bit index to tail_call" fails when > bpf_jit_enable=1, because the tail call is not executed. > > This in turn is because the generated code assumes index is 64-bit, > while it must be 32-bit, and as a result prog array bounds check fails, > while it should pass. Even if bounds check would have passed, the code > that follows uses 64-bit index to compute prog array offset. > > Fix by using clrj instead of clgrj for comparing index with array size, > and also by using llgfr for truncating index to 32 bits before using it > to compute prog array offset. > > Fixes: 6651ee070b31 ("s390/bpf: implement bpf_tail_call() helper") > Reported-by: Yauheni Kaliuta <yauheni.kaliuta@redhat.com> > Acked-by: Vasily Gorbik <gor@linux.ibm.com> > Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> Applied, thanks!
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 6299156f9738..955eb355c2fd 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -1049,8 +1049,8 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i /* llgf %w1,map.max_entries(%b2) */ EMIT6_DISP_LH(0xe3000000, 0x0016, REG_W1, REG_0, BPF_REG_2, offsetof(struct bpf_array, map.max_entries)); - /* clgrj %b3,%w1,0xa,label0: if %b3 >= %w1 goto out */ - EMIT6_PCREL_LABEL(0xec000000, 0x0065, BPF_REG_3, + /* clrj %b3,%w1,0xa,label0: if (u32)%b3 >= (u32)%w1 goto out */ + EMIT6_PCREL_LABEL(0xec000000, 0x0077, BPF_REG_3, REG_W1, 0, 0xa); /* @@ -1076,8 +1076,10 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i * goto out; */ - /* sllg %r1,%b3,3: %r1 = index * 8 */ - EMIT6_DISP_LH(0xeb000000, 0x000d, REG_1, BPF_REG_3, REG_0, 3); + /* llgfr %r1,%b3: %r1 = (u32) index */ + EMIT4(0xb9160000, REG_1, BPF_REG_3); + /* sllg %r1,%r1,3: %r1 *= 8 */ + EMIT6_DISP_LH(0xeb000000, 0x000d, REG_1, REG_1, REG_0, 3); /* lg %r1,prog(%b2,%r1) */ EMIT6_DISP_LH(0xe3000000, 0x0004, REG_1, BPF_REG_2, REG_1, offsetof(struct bpf_array, ptrs));