Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 30d3d94c authored by Zi Shen Lim's avatar Zi Shen Lim Committed by Catalin Marinas
Browse files

arm64: bpf: add 'load 64-bit immediate' instruction



Commit 02ab695b (net: filter: add "load 64-bit immediate" eBPF
instruction) introduced a new eBPF instruction. Let's add support
for this for arm64 as well.

Our arm64 eBPF JIT compiler now passes the new "load 64-bit
immediate" test case introduced in the same commit 02ab695b.

Signed-off-by: default avatarZi Shen Lim <zlim.lnx@gmail.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent d65a634a
Loading
Loading
Loading
Loading
+31 −0
Original line number Original line Diff line number Diff line
@@ -205,6 +205,12 @@ static void build_epilogue(struct jit_ctx *ctx)
	emit(A64_RET(A64_LR), ctx);
	emit(A64_RET(A64_LR), ctx);
}
}


/* JITs an eBPF instruction.
 * Returns:
 * 0  - successfully JITed an 8-byte eBPF instruction.
 * >0 - successfully JITed a 16-byte eBPF instruction.
 * <0 - failed to JIT.
 */
static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
{
{
	const u8 code = insn->code;
	const u8 code = insn->code;
@@ -464,6 +470,27 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
		emit(A64_B(jmp_offset), ctx);
		emit(A64_B(jmp_offset), ctx);
		break;
		break;


	/* dst = imm64 */
	case BPF_LD | BPF_IMM | BPF_DW:
	{
		const struct bpf_insn insn1 = insn[1];
		u64 imm64;

		if (insn1.code != 0 || insn1.src_reg != 0 ||
		    insn1.dst_reg != 0 || insn1.off != 0) {
			/* Note: verifier in BPF core must catch invalid
			 * instructions.
			 */
			pr_err_once("Invalid BPF_LD_IMM64 instruction\n");
			return -EINVAL;
		}

		imm64 = (u64)insn1.imm << 32 | imm;
		emit_a64_mov_i64(dst, imm64, ctx);

		return 1;
	}

	/* LDX: dst = *(size *)(src + off) */
	/* LDX: dst = *(size *)(src + off) */
	case BPF_LDX | BPF_MEM | BPF_W:
	case BPF_LDX | BPF_MEM | BPF_W:
	case BPF_LDX | BPF_MEM | BPF_H:
	case BPF_LDX | BPF_MEM | BPF_H:
@@ -615,6 +642,10 @@ static int build_body(struct jit_ctx *ctx)
			ctx->offset[i] = ctx->idx;
			ctx->offset[i] = ctx->idx;


		ret = build_insn(insn, ctx);
		ret = build_insn(insn, ctx);
		if (ret > 0) {
			i++;
			continue;
		}
		if (ret)
		if (ret)
			return ret;
			return ret;
	}
	}