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 <yangtiezhu@loongson.cn>
Tested-by: Vincent Li <vincent.mc.li@gmail.com>
Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
This commit is contained in:
Hengqi Chen 2026-02-10 19:31:18 +08:00 committed by Huacai Chen
parent ef54c517a9
commit 4fdb5dd8ae
2 changed files with 16 additions and 0 deletions

View file

@ -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)
{

View file

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