bpf, riscv: Add support for timed may_goto

Implement arch_bpf_timed_may_goto() for the RV64 JIT. The argument and
return value are carried in BPF_REG_AX, and BPF R0-R5 are preserved
across the call to the generic bpf_check_timed_may_goto().

Enable bpf_jit_supports_timed_may_goto() so the verifier uses the timed
expansion path.

Signed-off-by: Feng Jiang <jiangfeng@kylinos.cn>
Reviewed-by: Pu Lehui <pulehui@huawei.com>
Reviewed-by: Björn Töpel <bjorn@kernel.org>
Acked-by: Björn Töpel <bjorn@kernel.org>
Link: https://lore.kernel.org/bpf/20260723-riscv-bpf-timed-may-goto-v5-1-86acb54e5642@kylinos.cn
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
This commit is contained in:
Feng Jiang
2026-07-23 05:41:32 +00:00
committed by Kumar Kartikeya Dwivedi
parent 87267b8945
commit 6ef8ff20c3
3 changed files with 59 additions and 2 deletions

View File

@@ -3,7 +3,7 @@
obj-$(CONFIG_BPF_JIT) += bpf_jit_core.o
ifeq ($(CONFIG_ARCH_RV64I),y)
obj-$(CONFIG_BPF_JIT) += bpf_jit_comp64.o
obj-$(CONFIG_BPF_JIT) += bpf_jit_comp64.o bpf_timed_may_goto.o
else
obj-$(CONFIG_BPF_JIT) += bpf_jit_comp32.o
endif

View File

@@ -1841,7 +1841,12 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
if (aux->tail_call_reachable && insn->src_reg == BPF_PSEUDO_CALL)
emit_sd(RV_REG_SP, ctx->tcc_offset, RV_REG_TCC, ctx);
if (insn->src_reg != BPF_PSEUDO_CALL)
/*
* arch_bpf_timed_may_goto() is emitted by the verifier and
* returns its result in BPF_REG_AX instead of BPF_REG_0, so
* skip the normal "move return register into R0".
*/
if (insn->src_reg != BPF_PSEUDO_CALL && addr != (u64)arch_bpf_timed_may_goto)
emit_mv(bpf_to_rv_reg(BPF_REG_0, ctx), RV_REG_A0, ctx);
break;
}
@@ -2161,3 +2166,8 @@ bool bpf_jit_supports_subprog_tailcalls(void)
{
return true;
}
bool bpf_jit_supports_timed_may_goto(void)
{
return true;
}

View File

@@ -0,0 +1,47 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2026 Feng Jiang <jiangfeng@kylinos.cn> */
#include <linux/linkage.h>
#include <asm/asm.h>
/*
* Trampoline for the BPF timed may_goto loop bound. Custom calling convention:
* - input: stack offset in BPF_REG_AX (t0)
* - output: updated count in BPF_REG_AX (t0)
*
* Calls bpf_check_timed_may_goto(ptr) with the standard RISC-V ABI, where
* ptr = BPF_REG_FP (s5) + BPF_REG_AX (t0). BPF R0-R5 (a5, a0-a4) are saved
* across the call; BPF_REG_FP (s5) is callee-saved and needs no saving.
*/
SYM_FUNC_START(arch_bpf_timed_may_goto)
addi sp, sp, -(8*SZREG)
REG_S ra, 7*SZREG(sp)
REG_S s0, 6*SZREG(sp)
addi s0, sp, 8*SZREG
/* Save BPF registers R0-R5 (a5, a0-a4) */
REG_S a5, 5*SZREG(sp)
REG_S a0, 4*SZREG(sp)
REG_S a1, 3*SZREG(sp)
REG_S a2, 2*SZREG(sp)
REG_S a3, 1*SZREG(sp)
REG_S a4, 0*SZREG(sp)
add a0, t0, s5
call bpf_check_timed_may_goto
mv t0, a0
/* Restore BPF registers R0-R5 */
REG_L a4, 0*SZREG(sp)
REG_L a3, 1*SZREG(sp)
REG_L a2, 2*SZREG(sp)
REG_L a1, 3*SZREG(sp)
REG_L a0, 4*SZREG(sp)
REG_L a5, 5*SZREG(sp)
REG_L s0, 6*SZREG(sp)
REG_L ra, 7*SZREG(sp)
addi sp, sp, 8*SZREG
ret
SYM_FUNC_END(arch_bpf_timed_may_goto)