summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Guo <guodongtai@kylinos.cn>2026-08-17 22:07:40 +0800
committerHuacai Chen <chenhuacai@loongson.cn>2026-08-17 22:07:40 +0800
commit1db6d003e93d033fca25bcfbef73e2780a7e46d7 (patch)
tree4462d0110235287545d95275a7cd473aa90e1b01
parent1fec6bbc09e3066a0f39d85741df2a7877c97945 (diff)
downloadlinux-1db6d003e93d033fca25bcfbef73e2780a7e46d7.tar.gz
linux-1db6d003e93d033fca25bcfbef73e2780a7e46d7.zip
LoongArch: BPF: Resolve per-CPU addrs for internal-only MOV
Add support for the internal-only BPF_MOV instruction that resolves the absolute addresses of the per-CPU data from their per-CPU offsets. 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 register (a.k.a. __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(). Acked-by: Tiezhu Yang <yangtiezhu@loongson.cn> Tested-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: George Guo <guodongtai@kylinos.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
-rw-r--r--arch/loongarch/include/asm/inst.h1
-rw-r--r--arch/loongarch/net/bpf_jit.c14
2 files changed, 15 insertions, 0 deletions
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 d2ce187d1e23..4e56da413752 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);
@@ -2371,6 +2380,11 @@ bool bpf_jit_supports_fsession(void)
return true;
}
+bool bpf_jit_supports_percpu_insn(void)
+{
+ return true;
+}
+
bool bpf_jit_supports_ptr_xchg(void)
{
return true;