Skip to content

Commit 5356ba1

Browse files
iii-iborkmann
authored andcommitted
s390/bpf: Fix unwinding past the trampoline
When functions called by the trampoline panic, the backtrace that is printed stops at the trampoline, because the trampoline does not store its caller's frame address (backchain) on stack; it also stores the return address at a wrong location. Store both the same way as is already done for the regular eBPF programs. Fixes: 528eb2c ("s390/bpf: Implement arch_prepare_bpf_trampoline()") Signed-off-by: Ilya Leoshkevich <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent ce10fc0 commit 5356ba1

File tree

1 file changed

+14
-3
lines changed

1 file changed

+14
-3
lines changed

arch/s390/net/bpf_jit_comp.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2066,6 +2066,7 @@ struct bpf_tramp_jit {
20662066
* func_addr's original caller
20672067
*/
20682068
int stack_size; /* Trampoline stack size */
2069+
int backchain_off; /* Offset of backchain */
20692070
int stack_args_off; /* Offset of stack arguments for calling
20702071
* func_addr, has to be at the top
20712072
*/
@@ -2086,9 +2087,10 @@ struct bpf_tramp_jit {
20862087
* for __bpf_prog_enter() return value and
20872088
* func_addr respectively
20882089
*/
2089-
int r14_off; /* Offset of saved %r14 */
20902090
int run_ctx_off; /* Offset of struct bpf_tramp_run_ctx */
20912091
int tccnt_off; /* Offset of saved tailcall counter */
2092+
int r14_off; /* Offset of saved %r14, has to be at the
2093+
* bottom */
20922094
int do_fexit; /* do_fexit: label */
20932095
};
20942096

@@ -2247,19 +2249,23 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
22472249
* Calculate the stack layout.
22482250
*/
22492251

2250-
/* Reserve STACK_FRAME_OVERHEAD bytes for the callees. */
2252+
/*
2253+
* Allocate STACK_FRAME_OVERHEAD bytes for the callees. As the s390x
2254+
* ABI requires, put our backchain at the end of the allocated memory.
2255+
*/
22512256
tjit->stack_size = STACK_FRAME_OVERHEAD;
2257+
tjit->backchain_off = tjit->stack_size - sizeof(u64);
22522258
tjit->stack_args_off = alloc_stack(tjit, nr_stack_args * sizeof(u64));
22532259
tjit->reg_args_off = alloc_stack(tjit, nr_reg_args * sizeof(u64));
22542260
tjit->ip_off = alloc_stack(tjit, sizeof(u64));
22552261
tjit->arg_cnt_off = alloc_stack(tjit, sizeof(u64));
22562262
tjit->bpf_args_off = alloc_stack(tjit, nr_bpf_args * sizeof(u64));
22572263
tjit->retval_off = alloc_stack(tjit, sizeof(u64));
22582264
tjit->r7_r8_off = alloc_stack(tjit, 2 * sizeof(u64));
2259-
tjit->r14_off = alloc_stack(tjit, sizeof(u64));
22602265
tjit->run_ctx_off = alloc_stack(tjit,
22612266
sizeof(struct bpf_tramp_run_ctx));
22622267
tjit->tccnt_off = alloc_stack(tjit, sizeof(u64));
2268+
tjit->r14_off = alloc_stack(tjit, sizeof(u64) * 2);
22632269
/*
22642270
* In accordance with the s390x ABI, the caller has allocated
22652271
* STACK_FRAME_OVERHEAD bytes for us. 8 of them contain the caller's
@@ -2268,8 +2274,13 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
22682274
tjit->stack_size -= STACK_FRAME_OVERHEAD - sizeof(u64);
22692275
tjit->orig_stack_args_off = tjit->stack_size + STACK_FRAME_OVERHEAD;
22702276

2277+
/* lgr %r1,%r15 */
2278+
EMIT4(0xb9040000, REG_1, REG_15);
22712279
/* aghi %r15,-stack_size */
22722280
EMIT4_IMM(0xa70b0000, REG_15, -tjit->stack_size);
2281+
/* stg %r1,backchain_off(%r15) */
2282+
EMIT6_DISP_LH(0xe3000000, 0x0024, REG_1, REG_0, REG_15,
2283+
tjit->backchain_off);
22732284
/* mvc tccnt_off(4,%r15),stack_size+STK_OFF_TCCNT(%r15) */
22742285
_EMIT6(0xd203f000 | tjit->tccnt_off,
22752286
0xf000 | (tjit->stack_size + STK_OFF_TCCNT));

0 commit comments

Comments
 (0)