Commit 878ee3c3 authored by Alexei Starovoitov's avatar Alexei Starovoitov
Browse files

Merge branch 'bpf-arm64-indirect-jumps'

Puranjay Mohan says:

====================
bpf: arm64: Indirect jumps

Changes in v1->v2:
v1: https://lore.kernel.org/all/20251117004656.33292-1-puranjay@kernel.org/


- Dropped patch 3 that was ignoring relocations for .jumptables. LLVM
  has been fixed to not emit relocations for .jumptables, so this patch
  is not needed.
- Added Reviewed-by: default avatarAnton Protopopov <a.s.protopopov@gmail.com>

This set adds the support of indirect jumps to the arm64 JIT. It
involves calling bpf_prog_update_insn_ptrs() to support instructions
array map. The second piece is supporting BPF_JMP|BPF_X|BPF_JA, SRC=0,
DST=Rx, off=0, imm=0 instruction that is trivial to implement on arm64.

The final patch enables selftests on arm64:

 [root@localhost bpf]# ./test_progs-cpuv4 -a "*gotox*"
 #20/1    bpf_gotox/one-switch:OK
 #20/2    bpf_gotox/one-switch-non-zero-sec-offset:OK
 #20/3    bpf_gotox/two-switches:OK
 #20/4    bpf_gotox/big-jump-table:OK
 #20/5    bpf_gotox/static-global:OK
 #20/6    bpf_gotox/nonstatic-global:OK
 #20/7    bpf_gotox/other-sec:OK
 #20/8    bpf_gotox/static-global-other-sec:OK
 #20/9    bpf_gotox/nonstatic-global-other-sec:OK
 #20/10   bpf_gotox/one-jump-two-maps:OK
 #20/11   bpf_gotox/one-map-two-jumps:OK
 #20      bpf_gotox:OK
 #537/1   verifier_gotox/jump_table_ok:OK
 #537/2   verifier_gotox/jump_table_reserved_field_src_reg:OK
 #537/3   verifier_gotox/jump_table_reserved_field_non_zero_off:OK
 #537/4   verifier_gotox/jump_table_reserved_field_non_zero_imm:OK
 #537/5   verifier_gotox/jump_table_no_jump_table:OK
 #537/6   verifier_gotox/jump_table_incorrect_dst_reg_type:OK
 #537/7   verifier_gotox/jump_table_invalid_read_size_u32:OK
 #537/8   verifier_gotox/jump_table_invalid_read_size_u16:OK
 #537/9   verifier_gotox/jump_table_invalid_read_size_u8:OK
 #537/10  verifier_gotox/jump_table_misaligned_access:OK
 #537/11  verifier_gotox/jump_table_invalid_mem_acceess_pos:OK
 #537/12  verifier_gotox/jump_table_invalid_mem_acceess_neg:OK
 #537/13  verifier_gotox/jump_table_add_sub_ok:OK
 #537/14  verifier_gotox/jump_table_no_writes:OK
 #537/15  verifier_gotox/jump_table_use_reg_r0:OK
 #537/16  verifier_gotox/jump_table_use_reg_r1:OK
 #537/17  verifier_gotox/jump_table_use_reg_r2:OK
 #537/18  verifier_gotox/jump_table_use_reg_r3:OK
 #537/19  verifier_gotox/jump_table_use_reg_r4:OK
 #537/20  verifier_gotox/jump_table_use_reg_r5:OK
 #537/21  verifier_gotox/jump_table_use_reg_r6:OK
 #537/22  verifier_gotox/jump_table_use_reg_r7:OK
 #537/23  verifier_gotox/jump_table_use_reg_r8:OK
 #537/24  verifier_gotox/jump_table_use_reg_r9:OK
 #537/25  verifier_gotox/jump_table_outside_subprog:OK
 #537/26  verifier_gotox/jump_table_contains_non_unique_values:OK
 #537     verifier_gotox:OK
 Summary: 2/37 PASSED, 0 SKIPPED, 0 FAILED
====================

Link: https://patch.msgid.link/20251117130732.11107-1-puranjay@kernel.org


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parents 792f2588 d8774a36
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -1452,6 +1452,10 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
		emit(A64_ASR(is64, dst, dst, imm), ctx);
		break;

	/* JUMP reg */
	case BPF_JMP | BPF_JA | BPF_X:
		emit(A64_BR(dst), ctx);
		break;
	/* JUMP off */
	case BPF_JMP | BPF_JA:
	case BPF_JMP32 | BPF_JA:
@@ -2231,6 +2235,13 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
		for (i = 0; i <= prog->len; i++)
			ctx.offset[i] *= AARCH64_INSN_SIZE;
		bpf_prog_fill_jited_linfo(prog, ctx.offset + 1);
		/*
		 * The bpf_prog_update_insn_ptrs function expects offsets to
		 * point to the first byte of the jitted instruction (unlike
		 * the bpf_prog_fill_jited_linfo above, which, for historical
		 * reasons, expects to point to the next instruction)
		 */
		bpf_prog_update_insn_ptrs(prog, ctx.offset, ctx.ro_image);
out_off:
		if (!ro_header && priv_stack_ptr) {
			free_percpu(priv_stack_ptr);
+2 −2
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@
#include "bpf_misc.h"
#include "../../../include/linux/filter.h"

#ifdef __TARGET_ARCH_x86
#if defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)

#define DEFINE_SIMPLE_JUMP_TABLE_PROG(NAME, SRC_REG, OFF, IMM, OUTCOME)	\
									\
@@ -384,6 +384,6 @@ jt0_%=: \
	: __clobber_all);
}

#endif /* __TARGET_ARCH_x86 */
#endif /* __TARGET_ARCH_x86 || __TARGET_ARCH_arm64 */

char _license[] SEC("license") = "GPL";