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

Commit 02ab695bb37e (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 02ab695bb37e.

Signed-off-by: Zi 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: Catalin Marinas <catalin.marinas@arm.com>

authored by Zi Shen Lim and committed by Catalin Marinas 30d3d94c d65a634a

+31
+31
arch/arm64/net/bpf_jit_comp.c
··· 205 205 emit(A64_RET(A64_LR), ctx); 206 206 } 207 207 208 + /* JITs an eBPF instruction. 209 + * Returns: 210 + * 0 - successfully JITed an 8-byte eBPF instruction. 211 + * >0 - successfully JITed a 16-byte eBPF instruction. 212 + * <0 - failed to JIT. 213 + */ 208 214 static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) 209 215 { 210 216 const u8 code = insn->code; ··· 470 464 emit(A64_B(jmp_offset), ctx); 471 465 break; 472 466 467 + /* dst = imm64 */ 468 + case BPF_LD | BPF_IMM | BPF_DW: 469 + { 470 + const struct bpf_insn insn1 = insn[1]; 471 + u64 imm64; 472 + 473 + if (insn1.code != 0 || insn1.src_reg != 0 || 474 + insn1.dst_reg != 0 || insn1.off != 0) { 475 + /* Note: verifier in BPF core must catch invalid 476 + * instructions. 477 + */ 478 + pr_err_once("Invalid BPF_LD_IMM64 instruction\n"); 479 + return -EINVAL; 480 + } 481 + 482 + imm64 = (u64)insn1.imm << 32 | imm; 483 + emit_a64_mov_i64(dst, imm64, ctx); 484 + 485 + return 1; 486 + } 487 + 473 488 /* LDX: dst = *(size *)(src + off) */ 474 489 case BPF_LDX | BPF_MEM | BPF_W: 475 490 case BPF_LDX | BPF_MEM | BPF_H: ··· 642 615 ctx->offset[i] = ctx->idx; 643 616 644 617 ret = build_insn(insn, ctx); 618 + if (ret > 0) { 619 + i++; 620 + continue; 621 + } 645 622 if (ret) 646 623 return ret; 647 624 }