From: Hengqi Chen Date: Tue, 10 Feb 2026 11:31:18 +0000 (+0800) Subject: LoongArch: BPF: Implement bpf_addr_space_cast instruction X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4fdb5dd8aeba3a6b5ffc9c66fd0c8528fd835065;p=thirdparty%2Fkernel%2Fstable.git LoongArch: BPF: Implement bpf_addr_space_cast instruction LLVM generates bpf_addr_space_cast instruction while translating pointers between native (zero) address space and __attribute__((address_space(N))). The addr_space=0 is reserved as bpf_arena address space. rY = addr_space_cast(rX, 0, 1) is processed by the verifier and converted to normal 32-bit move: wX = wY rY = addr_space_cast(rX, 1, 0) has to be converted by JIT. With this, the following test cases passed: $ ./test_progs -a arena_htab,arena_list,arena_strsearch,verifier_arena,verifier_arena_large #4/1 arena_htab/arena_htab_llvm:OK #4/2 arena_htab/arena_htab_asm:OK #4 arena_htab:OK #5/1 arena_list/arena_list_1:OK #5/2 arena_list/arena_list_1000:OK #5 arena_list:OK #7/1 arena_strsearch/arena_strsearch:OK #7 arena_strsearch:OK #507/1 verifier_arena/basic_alloc1:OK #507/2 verifier_arena/basic_alloc2:OK #507/3 verifier_arena/basic_alloc3:OK #507/4 verifier_arena/basic_reserve1:OK #507/5 verifier_arena/basic_reserve2:OK #507/6 verifier_arena/reserve_twice:OK #507/7 verifier_arena/reserve_invalid_region:OK #507/8 verifier_arena/iter_maps1:OK #507/9 verifier_arena/iter_maps2:OK #507/10 verifier_arena/iter_maps3:OK #507 verifier_arena:OK #508/1 verifier_arena_large/big_alloc1:OK #508/2 verifier_arena_large/access_reserved:OK #508/3 verifier_arena_large/request_partially_reserved:OK #508/4 verifier_arena_large/free_reserved:OK #508/5 verifier_arena_large/big_alloc2:OK #508 verifier_arena_large:OK Summary: 5/20 PASSED, 0 SKIPPED, 0 FAILED Acked-by: Tiezhu Yang Tested-by: Vincent Li Signed-off-by: Hengqi Chen Signed-off-by: Huacai Chen --- diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c index b20ecc326a38..ceb7939088cd 100644 --- a/arch/loongarch/net/bpf_jit.c +++ b/arch/loongarch/net/bpf_jit.c @@ -559,6 +559,15 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext /* dst = src */ case BPF_ALU | BPF_MOV | BPF_X: case BPF_ALU64 | BPF_MOV | BPF_X: + if (insn_is_cast_user(insn)) { + move_reg(ctx, t1, src); + emit_zext_32(ctx, t1, true); + move_imm(ctx, dst, (ctx->user_vm_start >> 32) << 32, false); + emit_insn(ctx, beq, t1, LOONGARCH_GPR_ZERO, 1); + emit_insn(ctx, or, t1, dst, t1); + move_reg(ctx, dst, t1); + break; + } switch (off) { case 0: move_reg(ctx, dst, src); @@ -1955,6 +1964,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) memset(&ctx, 0, sizeof(ctx)); ctx.prog = prog; ctx.arena_vm_start = bpf_arena_get_kern_vm_start(prog->aux->arena); + ctx.user_vm_start = bpf_arena_get_user_vm_start(prog->aux->arena); ctx.offset = kvcalloc(prog->len + 1, sizeof(u32), GFP_KERNEL); if (ctx.offset == NULL) { @@ -2110,6 +2120,11 @@ bool bpf_jit_bypass_spec_v4(void) return true; } +bool bpf_jit_supports_arena(void) +{ + return true; +} + /* Indicate the JIT backend supports mixing bpf2bpf and tailcalls. */ bool bpf_jit_supports_subprog_tailcalls(void) { diff --git a/arch/loongarch/net/bpf_jit.h b/arch/loongarch/net/bpf_jit.h index 8816ac106f2f..a8e29be35fa8 100644 --- a/arch/loongarch/net/bpf_jit.h +++ b/arch/loongarch/net/bpf_jit.h @@ -21,6 +21,7 @@ struct jit_ctx { union loongarch_instruction *ro_image; u32 stack_size; u64 arena_vm_start; + u64 user_vm_start; }; struct jit_data {