Skip to content

Commit 7112cd2

Browse files
bjorn-rivosborkmann
authored andcommitted
riscv, bpf: Track both a0 (RISC-V ABI) and a5 (BPF) return values
The RISC-V BPF uses a5 for BPF return values, which are zero-extended, whereas the RISC-V ABI uses a0 which is sign-extended. In other words, a5 and a0 can differ, and are used in different context. The BPF trampoline are used for both BPF programs, and regular kernel functions. Make sure that the RISC-V BPF trampoline saves, and restores both a0 and a5. Fixes: 49b5e77 ("riscv, bpf: Add bpf trampoline support for RV64") Signed-off-by: Björn Töpel <bjorn@rivosinc.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20231004120706.52848-3-bjorn@kernel.org
1 parent 2f1b0d3 commit 7112cd2

1 file changed

Lines changed: 9 additions & 4 deletions

File tree

arch/riscv/net/bpf_jit_comp64.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -759,8 +759,10 @@ static int invoke_bpf_prog(struct bpf_tramp_link *l, int args_off, int retval_of
759759
if (ret)
760760
return ret;
761761

762-
if (save_ret)
763-
emit_sd(RV_REG_FP, -retval_off, regmap[BPF_REG_0], ctx);
762+
if (save_ret) {
763+
emit_sd(RV_REG_FP, -retval_off, RV_REG_A0, ctx);
764+
emit_sd(RV_REG_FP, -(retval_off - 8), regmap[BPF_REG_0], ctx);
765+
}
764766

765767
/* update branch with beqz */
766768
if (ctx->insns) {
@@ -853,7 +855,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
853855

854856
save_ret = flags & (BPF_TRAMP_F_CALL_ORIG | BPF_TRAMP_F_RET_FENTRY_RET);
855857
if (save_ret) {
856-
stack_size += 8;
858+
stack_size += 16; /* Save both A5 (BPF R0) and A0 */
857859
retval_off = stack_size;
858860
}
859861

@@ -957,6 +959,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
957959
if (ret)
958960
goto out;
959961
emit_sd(RV_REG_FP, -retval_off, RV_REG_A0, ctx);
962+
emit_sd(RV_REG_FP, -(retval_off - 8), regmap[BPF_REG_0], ctx);
960963
im->ip_after_call = ctx->insns + ctx->ninsns;
961964
/* 2 nops reserved for auipc+jalr pair */
962965
emit(rv_nop(), ctx);
@@ -988,8 +991,10 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
988991
if (flags & BPF_TRAMP_F_RESTORE_REGS)
989992
restore_args(nregs, args_off, ctx);
990993

991-
if (save_ret)
994+
if (save_ret) {
992995
emit_ld(RV_REG_A0, -retval_off, RV_REG_FP, ctx);
996+
emit_ld(regmap[BPF_REG_0], -(retval_off - 8), RV_REG_FP, ctx);
997+
}
993998

994999
emit_ld(RV_REG_S1, -sreg_off, RV_REG_FP, ctx);
9951000

0 commit comments

Comments
 (0)