Commit 4dd31243 authored by Puranjay Mohan's avatar Puranjay Mohan Committed by Alexei Starovoitov
Browse files

bpf: Add arm64 JIT support for 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) : used to convert a bpf arena pointer to
a pointer in the userspace vma. This has to be converted by the JIT.

Signed-off-by: default avatarPuranjay Mohan <puranjay12@gmail.com>
Link: https://lore.kernel.org/r/20240325150716.4387-3-puranjay12@gmail.com


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 339af577
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ struct jit_ctx {
	__le32 *ro_image;
	u32 stack_size;
	int fpb_offset;
	u64 user_vm_start;
};

struct bpf_plt {
@@ -868,6 +869,15 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
	/* dst = src */
	case BPF_ALU | BPF_MOV | BPF_X:
	case BPF_ALU64 | BPF_MOV | BPF_X:
		if (insn_is_cast_user(insn)) {
			emit(A64_MOV(0, tmp, src), ctx); // 32-bit mov clears the upper 32 bits
			emit_a64_mov_i(0, dst, ctx->user_vm_start >> 32, ctx);
			emit(A64_LSL(1, dst, dst, 32), ctx);
			emit(A64_CBZ(1, tmp, 2), ctx);
			emit(A64_ORR(1, tmp, dst, tmp), ctx);
			emit(A64_MOV(1, dst, tmp), ctx);
			break;
		}
		switch (insn->off) {
		case 0:
			emit(A64_MOV(is64, dst, src), ctx);
@@ -1690,6 +1700,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
	}

	ctx.fpb_offset = find_fpb_offset(prog);
	ctx.user_vm_start = bpf_arena_get_user_vm_start(prog->aux->arena);

	/*
	 * 1. Initial fake pass to compute ctx->idx and ctx->offset.
@@ -2511,6 +2522,11 @@ bool bpf_jit_supports_exceptions(void)
	return true;
}

bool bpf_jit_supports_arena(void)
{
	return true;
}

void bpf_jit_free(struct bpf_prog *prog)
{
	if (prog->jited) {
+0 −2
Original line number Diff line number Diff line
@@ -10,5 +10,3 @@ fill_link_info/kprobe_multi_link_info # bpf_program__attach_kprobe_mu
fill_link_info/kretprobe_multi_link_info         # bpf_program__attach_kprobe_multi_opts unexpected error: -95
fill_link_info/kprobe_multi_invalid_ubuff        # bpf_program__attach_kprobe_multi_opts unexpected error: -95
missed/kprobe_recursion                          # missed_kprobe_recursion__attach unexpected error: -95 (errno 95)
verifier_arena                                   # JIT does not support arena
arena_htab                                       # JIT does not support arena