Skip to content

Commit a2284d9

Browse files
borkmannAlexei Starovoitov
authored andcommitted
bpf, arm64: fix stack_depth tracking in combination with tail calls
Using dynamic stack_depth tracking in arm64 JIT is currently broken in combination with tail calls. In prologue, we cache ctx->stack_size and adjust SP reg for setting up function call stack, and tearing it down again in epilogue. Problem is that when doing a tail call, the cached ctx->stack_size might not be the same. One way to fix the problem with minimal overhead is to re-adjust SP in emit_bpf_tail_call() and properly adjust it to the current program's ctx->stack_size. Tested on Cavium ThunderX ARMv8. Fixes: f1c9eed ("bpf, arm64: take advantage of stack_depth tracking") Signed-off-by: Daniel Borkmann <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 68fda45 commit a2284d9

File tree

1 file changed

+11
-9
lines changed

1 file changed

+11
-9
lines changed

arch/arm64/net/bpf_jit_comp.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ static inline int epilogue_offset(const struct jit_ctx *ctx)
148148
/* Stack must be multiples of 16B */
149149
#define STACK_ALIGN(sz) (((sz) + 15) & ~15)
150150

151-
#define PROLOGUE_OFFSET 8
151+
/* Tail call offset to jump into */
152+
#define PROLOGUE_OFFSET 7
152153

153154
static int build_prologue(struct jit_ctx *ctx)
154155
{
@@ -200,19 +201,19 @@ static int build_prologue(struct jit_ctx *ctx)
200201
/* Initialize tail_call_cnt */
201202
emit(A64_MOVZ(1, tcc, 0, 0), ctx);
202203

203-
/* 4 byte extra for skb_copy_bits buffer */
204-
ctx->stack_size = prog->aux->stack_depth + 4;
205-
ctx->stack_size = STACK_ALIGN(ctx->stack_size);
206-
207-
/* Set up function call stack */
208-
emit(A64_SUB_I(1, A64_SP, A64_SP, ctx->stack_size), ctx);
209-
210204
cur_offset = ctx->idx - idx0;
211205
if (cur_offset != PROLOGUE_OFFSET) {
212206
pr_err_once("PROLOGUE_OFFSET = %d, expected %d!\n",
213207
cur_offset, PROLOGUE_OFFSET);
214208
return -1;
215209
}
210+
211+
/* 4 byte extra for skb_copy_bits buffer */
212+
ctx->stack_size = prog->aux->stack_depth + 4;
213+
ctx->stack_size = STACK_ALIGN(ctx->stack_size);
214+
215+
/* Set up function call stack */
216+
emit(A64_SUB_I(1, A64_SP, A64_SP, ctx->stack_size), ctx);
216217
return 0;
217218
}
218219

@@ -260,11 +261,12 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx)
260261
emit(A64_LDR64(prg, tmp, prg), ctx);
261262
emit(A64_CBZ(1, prg, jmp_offset), ctx);
262263

263-
/* goto *(prog->bpf_func + prologue_size); */
264+
/* goto *(prog->bpf_func + prologue_offset); */
264265
off = offsetof(struct bpf_prog, bpf_func);
265266
emit_a64_mov_i64(tmp, off, ctx);
266267
emit(A64_LDR64(tmp, prg, tmp), ctx);
267268
emit(A64_ADD_I(1, tmp, tmp, sizeof(u32) * PROLOGUE_OFFSET), ctx);
269+
emit(A64_ADD_I(1, A64_SP, A64_SP, ctx->stack_size), ctx);
268270
emit(A64_BR(tmp), ctx);
269271

270272
/* out: */

0 commit comments

Comments
 (0)