Skip to content

Commit a192103

Browse files
iii-iborkmann
authored andcommitted
s390/bpf: Pass through tail call counter in trampolines
s390x eBPF programs use the following extension to the s390x calling convention: tail call counter is passed on stack at offset STK_OFF_TCCNT, which callees otherwise use as scratch space. Currently trampoline does not respect this and clobbers tail call counter. This breaks enforcing tail call limits in eBPF programs, which have trampolines attached to them. Fix by forwarding a copy of the tail call counter to the original eBPF program in the trampoline (for fexit), and by restoring it at the end of the trampoline (for fentry). Fixes: 528eb2c ("s390/bpf: Implement arch_prepare_bpf_trampoline()") Reported-by: Leon Hwang <[email protected]> Signed-off-by: Ilya Leoshkevich <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 6764e76 commit a192103

File tree

1 file changed

+10
-0
lines changed

1 file changed

+10
-0
lines changed

arch/s390/net/bpf_jit_comp.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2088,6 +2088,7 @@ struct bpf_tramp_jit {
20882088
*/
20892089
int r14_off; /* Offset of saved %r14 */
20902090
int run_ctx_off; /* Offset of struct bpf_tramp_run_ctx */
2091+
int tccnt_off; /* Offset of saved tailcall counter */
20912092
int do_fexit; /* do_fexit: label */
20922093
};
20932094

@@ -2258,12 +2259,16 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
22582259
tjit->r14_off = alloc_stack(tjit, sizeof(u64));
22592260
tjit->run_ctx_off = alloc_stack(tjit,
22602261
sizeof(struct bpf_tramp_run_ctx));
2262+
tjit->tccnt_off = alloc_stack(tjit, sizeof(u64));
22612263
/* The caller has already reserved STACK_FRAME_OVERHEAD bytes. */
22622264
tjit->stack_size -= STACK_FRAME_OVERHEAD;
22632265
tjit->orig_stack_args_off = tjit->stack_size + STACK_FRAME_OVERHEAD;
22642266

22652267
/* aghi %r15,-stack_size */
22662268
EMIT4_IMM(0xa70b0000, REG_15, -tjit->stack_size);
2269+
/* mvc tccnt_off(4,%r15),stack_size+STK_OFF_TCCNT(%r15) */
2270+
_EMIT6(0xd203f000 | tjit->tccnt_off,
2271+
0xf000 | (tjit->stack_size + STK_OFF_TCCNT));
22672272
/* stmg %r2,%rN,fwd_reg_args_off(%r15) */
22682273
if (nr_reg_args)
22692274
EMIT6_DISP_LH(0xeb000000, 0x0024, REG_2,
@@ -2400,6 +2405,8 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
24002405
(nr_stack_args * sizeof(u64) - 1) << 16 |
24012406
tjit->stack_args_off,
24022407
0xf000 | tjit->orig_stack_args_off);
2408+
/* mvc STK_OFF_TCCNT(4,%r15),tccnt_off(%r15) */
2409+
_EMIT6(0xd203f000 | STK_OFF_TCCNT, 0xf000 | tjit->tccnt_off);
24032410
/* lgr %r1,%r8 */
24042411
EMIT4(0xb9040000, REG_1, REG_8);
24052412
/* %r1() */
@@ -2456,6 +2463,9 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
24562463
if (flags & (BPF_TRAMP_F_CALL_ORIG | BPF_TRAMP_F_RET_FENTRY_RET))
24572464
EMIT6_DISP_LH(0xe3000000, 0x0004, REG_2, REG_0, REG_15,
24582465
tjit->retval_off);
2466+
/* mvc stack_size+STK_OFF_TCCNT(4,%r15),tccnt_off(%r15) */
2467+
_EMIT6(0xd203f000 | (tjit->stack_size + STK_OFF_TCCNT),
2468+
0xf000 | tjit->tccnt_off);
24592469
/* aghi %r15,stack_size */
24602470
EMIT4_IMM(0xa70b0000, REG_15, tjit->stack_size);
24612471
/* Emit an expoline for the following indirect jump. */

0 commit comments

Comments
 (0)