| From f1003b787c00fbaa4b11619c6b23a885bfce8f07 Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= <bjorn.topel@gmail.com> |
| Date: Mon, 16 Dec 2019 10:13:35 +0100 |
| Subject: riscv, bpf: Fix broken BPF tail calls |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Björn Töpel <bjorn.topel@gmail.com> |
| |
| commit f1003b787c00fbaa4b11619c6b23a885bfce8f07 upstream. |
| |
| The BPF JIT incorrectly clobbered the a0 register, and did not flag |
| usage of s5 register when BPF stack was being used. |
| |
| Fixes: 2353ecc6f91f ("bpf, riscv: add BPF JIT for RV64G") |
| Signed-off-by: Björn Töpel <bjorn.topel@gmail.com> |
| Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> |
| Link: https://lore.kernel.org/bpf/20191216091343.23260-2-bjorn.topel@gmail.com |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/riscv/net/bpf_jit_comp.c | 13 +++++++++++-- |
| 1 file changed, 11 insertions(+), 2 deletions(-) |
| |
| --- a/arch/riscv/net/bpf_jit_comp.c |
| +++ b/arch/riscv/net/bpf_jit_comp.c |
| @@ -120,6 +120,11 @@ static bool seen_reg(int reg, struct rv_ |
| 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) |
| { |
| __set_bit(RV_CTX_F_SEEN_CALL, &ctx->flags); |
| @@ -596,7 +601,8 @@ static void __build_epilogue(u8 reg, str |
| |
| emit(rv_addi(RV_REG_SP, RV_REG_SP, stack_adjust), ctx); |
| /* Set return value. */ |
| - emit(rv_addi(RV_REG_A0, RV_REG_A5, 0), ctx); |
| + if (reg == RV_REG_RA) |
| + emit(rv_addi(RV_REG_A0, RV_REG_A5, 0), ctx); |
| emit(rv_jalr(RV_REG_ZERO, reg, 0), ctx); |
| } |
| |
| @@ -1426,6 +1432,10 @@ static void build_prologue(struct rv_jit |
| { |
| 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)) |
| stack_adjust += 8; |
| stack_adjust += 8; /* RV_REG_FP */ |
| @@ -1443,7 +1453,6 @@ static void build_prologue(struct rv_jit |
| stack_adjust += 8; |
| |
| stack_adjust = round_up(stack_adjust, 16); |
| - bpf_stack_adjust = round_up(ctx->prog->aux->stack_depth, 16); |
| stack_adjust += bpf_stack_adjust; |
| |
| store_offset = stack_adjust - 8; |