From: George Guo Support the internal-only BPF_MOV instruction that resolves the absolute address of per-CPU data from its per-CPU offset. This instruction is used only for internal inlining optimizations between the BPF verifier and the JITs (e.g. inlining bpf_get_smp_processor_id() and per-CPU map lookups). LoongArch keeps the per-CPU offset of the current CPU in $r21 (__my_cpu_offset), so resolving a per-CPU address only requires adding $r21 to the source register holding the per-CPU offset. Advertise the capability via bpf_jit_supports_percpu_insn(). Signed-off-by: George Guo --- arch/loongarch/include/asm/inst.h | 1 + arch/loongarch/net/bpf_jit.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/arch/loongarch/include/asm/inst.h b/arch/loongarch/include/asm/inst.h index 54f35bcd0f66..585667e361c2 100644 --- a/arch/loongarch/include/asm/inst.h +++ b/arch/loongarch/include/asm/inst.h @@ -411,6 +411,7 @@ enum loongarch_gpr { LOONGARCH_GPR_T6, LOONGARCH_GPR_T7, LOONGARCH_GPR_T8, + LOONGARCH_GPR_U0 = 21, /* Kernel per-CPU base register ($r21) */ LOONGARCH_GPR_FP = 22, LOONGARCH_GPR_S0 = 23, LOONGARCH_GPR_S1, diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c index aa88f904a5ca..b8dd956d46bd 100644 --- a/arch/loongarch/net/bpf_jit.c +++ b/arch/loongarch/net/bpf_jit.c @@ -722,6 +722,15 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext move_reg(ctx, dst, t1); break; } + if (insn_is_mov_percpu_addr(insn)) { + if (dst != src) + move_reg(ctx, dst, src); +#ifdef CONFIG_SMP + /* dst += __my_cpu_offset, held in $r21 */ + emit_insn(ctx, addd, dst, dst, LOONGARCH_GPR_U0); +#endif + break; + } switch (off) { case 0: move_reg(ctx, dst, src); @@ -2376,6 +2385,11 @@ bool bpf_jit_supports_ptr_xchg(void) return true; } +bool bpf_jit_supports_percpu_insn(void) +{ + return true; +} + /* Indicate the JIT backend supports mixing bpf2bpf and tailcalls. */ bool bpf_jit_supports_subprog_tailcalls(void) { -- 2.53.0