Commit 4fdb5dd8 authored by Hengqi Chen's avatar Hengqi Chen Committed by Huacai Chen
Browse files

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: default avatarTiezhu Yang <yangtiezhu@loongson.cn>
Tested-by: default avatarVincent Li <vincent.mc.li@gmail.com>
Signed-off-by: default avatarHengqi Chen <hengqi.chen@gmail.com>
Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
parent ef54c517
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -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)
{
+1 −0
Original line number Diff line number Diff line
@@ -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 {