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>
This commit is contained in:
George Guo 2026-08-17 22:07:40 +08:00 committed by Huacai Chen
parent 1fec6bbc09
commit 1db6d003e9
2 changed files with 15 additions and 0 deletions

View File

@ -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,

View File

@ -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;