Preparation for moving kfunc address from bpf_insn.imm. Signed-off-by: Ilya Leoshkevich <iii@xxxxxxxxxxxxx> --- arch/arm/net/bpf_jit_32.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c index 6a1c9fca5260..b9a7f7bba811 100644 --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c @@ -1345,7 +1345,8 @@ static void build_epilogue(struct jit_ctx *ctx) * >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, + bool extra_pass) { const u8 code = insn->code; const s8 *dst = bpf2a32[insn->dst_reg]; @@ -1783,7 +1784,14 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) const s8 *r3 = bpf2a32[BPF_REG_3]; const s8 *r4 = bpf2a32[BPF_REG_4]; const s8 *r5 = bpf2a32[BPF_REG_5]; - const u32 func = (u32)__bpf_call_base + (u32)imm; + bool func_addr_fixed; + u64 func; + int err; + + err = bpf_jit_get_func_addr(ctx->prog, insn, extra_pass, + &func, &func_addr_fixed); + if (err) + return err; emit_a32_mov_r64(true, r0, r1, ctx); emit_a32_mov_r64(true, r1, r2, ctx); @@ -1791,7 +1799,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) emit_push_r64(r4, ctx); emit_push_r64(r3, ctx); - emit_a32_mov_i(tmp[1], func, ctx); + emit_a32_mov_i(tmp[1], (u32)func, ctx); emit_blx_r(tmp[1], ctx); emit(ARM_ADD_I(ARM_SP, ARM_SP, imm8m(24)), ctx); // callee clean @@ -1826,7 +1834,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) return 0; } -static int build_body(struct jit_ctx *ctx) +static int build_body(struct jit_ctx *ctx, bool extra_pass) { const struct bpf_prog *prog = ctx->prog; unsigned int i; @@ -1835,7 +1843,7 @@ static int build_body(struct jit_ctx *ctx) const struct bpf_insn *insn = &(prog->insnsi[i]); int ret; - ret = build_insn(insn, ctx); + ret = build_insn(insn, ctx, extra_pass); /* It's used with loading the 64 bit immediate value. */ if (ret > 0) { @@ -1880,6 +1888,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) struct jit_ctx ctx; unsigned int tmp_idx; unsigned int image_size; + bool extra_pass; u8 *image_ptr; /* If BPF JIT was not enabled then we must fall back to @@ -1901,6 +1910,10 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) prog = tmp; } + extra_pass = prog->aux->jit_data; + if (!extra_pass) + prog->aux->jit_data = bpf_int_jit_compile; + memset(&ctx, 0, sizeof(ctx)); ctx.prog = prog; ctx.cpu_architecture = cpu_architecture(); @@ -1924,7 +1937,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) * being successful in the second pass, so just fall back * to the interpreter. */ - if (build_body(&ctx)) { + if (build_body(&ctx, extra_pass)) { prog = orig_prog; goto out_off; } @@ -1982,7 +1995,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) /* If building the body of the JITed code fails somehow, * we fall back to the interpretation. */ - if (build_body(&ctx) < 0) { + if (build_body(&ctx, extra_pass) < 0) { image_ptr = NULL; bpf_jit_binary_free(header); prog = orig_prog; -- 2.39.1