Commit f1003b78 authored by Björn Töpel's avatar Björn Töpel Committed by Daniel Borkmann

riscv, bpf: Fix broken BPF tail calls

The BPF JIT incorrectly clobbered the a0 register, and did not flag
usage of s5 register when BPF stack was being used.

Fixes: 2353ecc6 ("bpf, riscv: add BPF JIT for RV64G")
Signed-off-by: default avatarBjörn Töpel <bjorn.topel@gmail.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20191216091343.23260-2-bjorn.topel@gmail.com
parent a352a824
...@@ -120,6 +120,11 @@ static bool seen_reg(int reg, struct rv_jit_context *ctx) ...@@ -120,6 +120,11 @@ static bool seen_reg(int reg, struct rv_jit_context *ctx)
return false; return false;
} }
static void mark_fp(struct rv_jit_context *ctx)
{
__set_bit(RV_CTX_F_SEEN_S5, &ctx->flags);
}
static void mark_call(struct rv_jit_context *ctx) static void mark_call(struct rv_jit_context *ctx)
{ {
__set_bit(RV_CTX_F_SEEN_CALL, &ctx->flags); __set_bit(RV_CTX_F_SEEN_CALL, &ctx->flags);
...@@ -596,6 +601,7 @@ static void __build_epilogue(u8 reg, struct rv_jit_context *ctx) ...@@ -596,6 +601,7 @@ static void __build_epilogue(u8 reg, struct rv_jit_context *ctx)
emit(rv_addi(RV_REG_SP, RV_REG_SP, stack_adjust), ctx); emit(rv_addi(RV_REG_SP, RV_REG_SP, stack_adjust), ctx);
/* Set return value. */ /* Set return value. */
if (reg == RV_REG_RA)
emit(rv_addi(RV_REG_A0, RV_REG_A5, 0), ctx); emit(rv_addi(RV_REG_A0, RV_REG_A5, 0), ctx);
emit(rv_jalr(RV_REG_ZERO, reg, 0), ctx); emit(rv_jalr(RV_REG_ZERO, reg, 0), ctx);
} }
...@@ -1426,6 +1432,10 @@ static void build_prologue(struct rv_jit_context *ctx) ...@@ -1426,6 +1432,10 @@ static void build_prologue(struct rv_jit_context *ctx)
{ {
int stack_adjust = 0, store_offset, bpf_stack_adjust; int stack_adjust = 0, store_offset, bpf_stack_adjust;
bpf_stack_adjust = round_up(ctx->prog->aux->stack_depth, 16);
if (bpf_stack_adjust)
mark_fp(ctx);
if (seen_reg(RV_REG_RA, ctx)) if (seen_reg(RV_REG_RA, ctx))
stack_adjust += 8; stack_adjust += 8;
stack_adjust += 8; /* RV_REG_FP */ stack_adjust += 8; /* RV_REG_FP */
...@@ -1443,7 +1453,6 @@ static void build_prologue(struct rv_jit_context *ctx) ...@@ -1443,7 +1453,6 @@ static void build_prologue(struct rv_jit_context *ctx)
stack_adjust += 8; stack_adjust += 8;
stack_adjust = round_up(stack_adjust, 16); stack_adjust = round_up(stack_adjust, 16);
bpf_stack_adjust = round_up(ctx->prog->aux->stack_depth, 16);
stack_adjust += bpf_stack_adjust; stack_adjust += bpf_stack_adjust;
store_offset = stack_adjust - 8; store_offset = stack_adjust - 8;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment