From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BBF68C6FA82 for ; Mon, 26 Sep 2022 20:29:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229664AbiIZU3w (ORCPT ); Mon, 26 Sep 2022 16:29:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52852 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229959AbiIZU3t (ORCPT ); Mon, 26 Sep 2022 16:29:49 -0400 Received: from www62.your-server.de (www62.your-server.de [213.133.104.62]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D74FB27B06; Mon, 26 Sep 2022 13:29:46 -0700 (PDT) Received: from sslproxy04.your-server.de ([78.46.152.42]) by www62.your-server.de with esmtpsa (TLSv1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.92.3) (envelope-from ) id 1ocujU-00008i-Nu; Mon, 26 Sep 2022 22:29:40 +0200 Received: from [85.1.206.226] (helo=linux-4.home) by sslproxy04.your-server.de with esmtpsa (TLSv1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1ocujU-000CTm-79; Mon, 26 Sep 2022 22:29:40 +0200 Subject: Re: [RESEND PATCH bpf-next 1/2] bpf, arm64: Jit BPF_CALL to direct call when possible To: Xu Kuohai , bpf@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: Jean-Philippe Brucker , Alexei Starovoitov , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Zi Shen Lim , Catalin Marinas , Will Deacon , mark.rutland@arm.com, revest@chromium.org References: <20220919092138.1027353-1-xukuohai@huaweicloud.com> <20220919092138.1027353-2-xukuohai@huaweicloud.com> From: Daniel Borkmann Message-ID: <21073277-5bbd-5555-88f2-76b07ad9b74f@iogearbox.net> Date: Mon, 26 Sep 2022 22:29:39 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.7.2 MIME-Version: 1.0 In-Reply-To: <20220919092138.1027353-2-xukuohai@huaweicloud.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Authenticated-Sender: daniel@iogearbox.net X-Virus-Scanned: Clear (ClamAV 0.103.6/26670/Mon Sep 26 10:00:52 2022) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org [ +Mark/Florent ] On 9/19/22 11:21 AM, Xu Kuohai wrote: > From: Xu Kuohai > > Currently BPF_CALL is always jited to indirect call, but when target is > in the range of direct call, BPF_CALL can be jited to direct call. > > For example, the following BPF_CALL > > call __htab_map_lookup_elem > > is always jited to an indirect call: > > mov x10, #0xffffffffffff18f4 > movk x10, #0x821, lsl #16 > movk x10, #0x8000, lsl #32 > blr x10 > > When the target is in the range of direct call, it can be jited to: > > bl 0xfffffffffd33bc98 > > This patch does such jit when possible. > > 1. First pass, get the maximum jited image size. Since the jited image > memory is not allocated yet, the distance between jited BPF_CALL > instructon and call target is unknown, so jit all BPF_CALL to indirect > call to get the maximum image size. > > 2. Allocate image memory with the size caculated in step 1. > > 3. Second pass, determine the jited address and size for every bpf instruction. > Since image memory is now allocated and there is only one jit method for > bpf instructions other than BPF_CALL, so the jited address for the first > BPF_CALL is determined, so the distance to call target is determined, so > the first BPF_CALL is determined to be jited to direct or indirect call, > so the jited image size after the first BPF_CALL is determined. By analogy, > the jited addresses and sizes for all subsequent BPF instructions are > determined. > > 4. Last pass, generate the final image. The jump offset of jump instruction > whose target is within the jited image is determined in this pass, since > the target instruction address may be changed in step 3. Wouldn't this require similar convergence process like in x86-64 JIT? You state the jump instructions are placed in step 4 because step 3 could have changed their offsets, but then after step 4, couldn't also again the offsets have changed for the target addresses from 3 again in some corner cases (given emit_a64_mov_i() is used also in jump encoding)? > Tested with test_bpf.ko and some arm64 working selftests, nothing failed. > > Signed-off-by: Xu Kuohai > --- > arch/arm64/net/bpf_jit_comp.c | 71 ++++++++++++++++++++++++++++------- > 1 file changed, 58 insertions(+), 13 deletions(-) > > diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c > index 30f76178608b..06437e34614b 100644 > --- a/arch/arm64/net/bpf_jit_comp.c > +++ b/arch/arm64/net/bpf_jit_comp.c > @@ -72,6 +72,7 @@ static const int bpf2a64[] = { > struct jit_ctx { > const struct bpf_prog *prog; > int idx; > + bool write; > int epilogue_offset; > int *offset; > int exentry_idx; > @@ -91,7 +92,7 @@ struct bpf_plt { > > static inline void emit(const u32 insn, struct jit_ctx *ctx) > { > - if (ctx->image != NULL) > + if (ctx->image != NULL && ctx->write) > ctx->image[ctx->idx] = cpu_to_le32(insn); > > ctx->idx++; > @@ -178,10 +179,29 @@ static inline void emit_addr_mov_i64(const int reg, const u64 val, > > static inline void emit_call(u64 target, struct jit_ctx *ctx) > { > - u8 tmp = bpf2a64[TMP_REG_1]; > + u8 tmp; > + long offset; > + unsigned long pc; > + u32 insn = AARCH64_BREAK_FAULT; > + > + /* if ctx->image == NULL or target == 0, the jump distance is unknown, > + * emit indirect call. > + */ > + if (ctx->image && target) { > + pc = (unsigned long)&ctx->image[ctx->idx]; > + offset = (long)target - (long)pc; > + if (offset >= -SZ_128M && offset < SZ_128M) > + insn = aarch64_insn_gen_branch_imm(pc, target, > + AARCH64_INSN_BRANCH_LINK); > + } > > - emit_addr_mov_i64(tmp, target, ctx); > - emit(A64_BLR(tmp), ctx); > + if (insn == AARCH64_BREAK_FAULT) { > + tmp = bpf2a64[TMP_REG_1]; > + emit_addr_mov_i64(tmp, target, ctx); > + emit(A64_BLR(tmp), ctx); > + } else { > + emit(insn, ctx); > + } > } > > static inline int bpf2a64_offset(int bpf_insn, int off, > @@ -1392,13 +1412,11 @@ static int build_body(struct jit_ctx *ctx, bool extra_pass) > const struct bpf_insn *insn = &prog->insnsi[i]; > int ret; > > - if (ctx->image == NULL) > - ctx->offset[i] = ctx->idx; > + ctx->offset[i] = ctx->idx; > ret = build_insn(insn, ctx, extra_pass); > if (ret > 0) { > i++; > - if (ctx->image == NULL) > - ctx->offset[i] = ctx->idx; > + ctx->offset[i] = ctx->idx; > continue; > } > if (ret) > @@ -1409,8 +1427,7 @@ static int build_body(struct jit_ctx *ctx, bool extra_pass) > * the last element with the offset after the last > * instruction (end of program) > */ > - if (ctx->image == NULL) > - ctx->offset[i] = ctx->idx; > + ctx->offset[i] = ctx->idx; > > return 0; > } > @@ -1461,6 +1478,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) > bool extra_pass = false; > struct jit_ctx ctx; > u8 *image_ptr; > + int body_idx; > + int exentry_idx; > > if (!prog->jit_requested) > return orig_prog; > @@ -1515,6 +1534,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) > goto out_off; > } > > + /* Get the max image size */ > if (build_body(&ctx, extra_pass)) { > prog = orig_prog; > goto out_off; > @@ -1528,7 +1548,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) > extable_size = prog->aux->num_exentries * > sizeof(struct exception_table_entry); > > - /* Now we know the actual image size. */ > + /* Now we know the max image size. */ > prog_size = sizeof(u32) * ctx.idx; > /* also allocate space for plt target */ > extable_offset = round_up(prog_size + PLT_TARGET_SIZE, extable_align); > @@ -1548,15 +1568,37 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) > skip_init_ctx: > ctx.idx = 0; > ctx.exentry_idx = 0; > + ctx.write = true; > > build_prologue(&ctx, was_classic); > > + /* Record exentry_idx and ctx.idx before first build_body */ > + exentry_idx = ctx.exentry_idx; > + body_idx = ctx.idx; > + /* Don't write instruction to memory for now */ > + ctx.write = false; > + > + /* Determine call distance and instruction position */ > if (build_body(&ctx, extra_pass)) { > bpf_jit_binary_free(header); > prog = orig_prog; > goto out_off; > } > > + ctx.epilogue_offset = ctx.idx; > + > + ctx.exentry_idx = exentry_idx; > + ctx.idx = body_idx; > + ctx.write = true; > + > + /* Determine jump offset and write result to memory */ > + if (build_body(&ctx, extra_pass) || > + WARN_ON_ONCE(ctx.idx != ctx.epilogue_offset)) { > + bpf_jit_binary_free(header); > + prog = orig_prog; > + goto out_off; > + } > + > build_epilogue(&ctx); > build_plt(&ctx); > > @@ -1567,6 +1609,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) > goto out_off; > } > > + /* Update prog size */ > + prog_size = sizeof(u32) * ctx.idx; > /* And we're done. */ > if (bpf_jit_enable > 1) > bpf_jit_dump(prog->len, prog_size, 2, ctx.image); > @@ -1574,8 +1618,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) > bpf_flush_icache(header, ctx.image + ctx.idx); > > if (!prog->is_func || extra_pass) { > - if (extra_pass && ctx.idx != jit_data->ctx.idx) { > - pr_err_once("multi-func JIT bug %d != %d\n", > + if (extra_pass && ctx.idx > jit_data->ctx.idx) { > + pr_err_once("multi-func JIT bug %d > %d\n", > ctx.idx, jit_data->ctx.idx); > bpf_jit_binary_free(header); > prog->bpf_func = NULL; > @@ -1976,6 +2020,7 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, > struct jit_ctx ctx = { > .image = NULL, > .idx = 0, > + .write = true, > }; > > /* the first 8 arguments are passed by registers */ > From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 57DC2C32771 for ; Mon, 26 Sep 2022 20:31:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:Content-Type: Content-Transfer-Encoding:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:Date:Message-ID:From: References:Cc:To:Subject:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=07zL7ffDGoEHTyu8HqznI4XCVj72XUN0nIzAamF+Ai8=; b=CmhojyQ1zUfqH2Wa+zd6VUJ2Jp PQCdq70qAL1r8u/gimANWCErxQVKCRXN91kOPYq1+uxfprGHE0jyKq5+k7C7T2toz1uP9P0BAcH23 /kZJEe+yLFrP/ZgQMzDyW+4cQgSLCGs1IVx7UwQs9oxLQadn4aQpcu4WMdtNPtzo9bRg/T1IPuUsS ni00X0TEN+yYWdu+cCy5T886wIunNuEAvgb54U9LKZh6GvxP7/sM3Ke1z8AgcBuTsYJGmkd3Rkqfb A0hjwTRuIIIsIUV4RDLCSvoaU6CaBBcDI2Tqi9LVMbk5DGnTZ2LIra4l2hChleRT2xH2iavCUiyNj 40WcKMEA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1ocujv-006jyC-8w; Mon, 26 Sep 2022 20:30:07 +0000 Received: from www62.your-server.de ([213.133.104.62]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1ocujq-006jwB-AT for linux-arm-kernel@lists.infradead.org; Mon, 26 Sep 2022 20:30:05 +0000 Received: from sslproxy04.your-server.de ([78.46.152.42]) by www62.your-server.de with esmtpsa (TLSv1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.92.3) (envelope-from ) id 1ocujU-00008i-Nu; Mon, 26 Sep 2022 22:29:40 +0200 Received: from [85.1.206.226] (helo=linux-4.home) by sslproxy04.your-server.de with esmtpsa (TLSv1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1ocujU-000CTm-79; Mon, 26 Sep 2022 22:29:40 +0200 Subject: Re: [RESEND PATCH bpf-next 1/2] bpf, arm64: Jit BPF_CALL to direct call when possible To: Xu Kuohai , bpf@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: Jean-Philippe Brucker , Alexei Starovoitov , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Zi Shen Lim , Catalin Marinas , Will Deacon , mark.rutland@arm.com, revest@chromium.org References: <20220919092138.1027353-1-xukuohai@huaweicloud.com> <20220919092138.1027353-2-xukuohai@huaweicloud.com> From: Daniel Borkmann Message-ID: <21073277-5bbd-5555-88f2-76b07ad9b74f@iogearbox.net> Date: Mon, 26 Sep 2022 22:29:39 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.7.2 MIME-Version: 1.0 In-Reply-To: <20220919092138.1027353-2-xukuohai@huaweicloud.com> Content-Language: en-US X-Authenticated-Sender: daniel@iogearbox.net X-Virus-Scanned: Clear (ClamAV 0.103.6/26670/Mon Sep 26 10:00:52 2022) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220926_133002_726287_D1D98B52 X-CRM114-Status: GOOD ( 38.19 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="us-ascii"; Format="flowed" Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org [ +Mark/Florent ] On 9/19/22 11:21 AM, Xu Kuohai wrote: > From: Xu Kuohai > > Currently BPF_CALL is always jited to indirect call, but when target is > in the range of direct call, BPF_CALL can be jited to direct call. > > For example, the following BPF_CALL > > call __htab_map_lookup_elem > > is always jited to an indirect call: > > mov x10, #0xffffffffffff18f4 > movk x10, #0x821, lsl #16 > movk x10, #0x8000, lsl #32 > blr x10 > > When the target is in the range of direct call, it can be jited to: > > bl 0xfffffffffd33bc98 > > This patch does such jit when possible. > > 1. First pass, get the maximum jited image size. Since the jited image > memory is not allocated yet, the distance between jited BPF_CALL > instructon and call target is unknown, so jit all BPF_CALL to indirect > call to get the maximum image size. > > 2. Allocate image memory with the size caculated in step 1. > > 3. Second pass, determine the jited address and size for every bpf instruction. > Since image memory is now allocated and there is only one jit method for > bpf instructions other than BPF_CALL, so the jited address for the first > BPF_CALL is determined, so the distance to call target is determined, so > the first BPF_CALL is determined to be jited to direct or indirect call, > so the jited image size after the first BPF_CALL is determined. By analogy, > the jited addresses and sizes for all subsequent BPF instructions are > determined. > > 4. Last pass, generate the final image. The jump offset of jump instruction > whose target is within the jited image is determined in this pass, since > the target instruction address may be changed in step 3. Wouldn't this require similar convergence process like in x86-64 JIT? You state the jump instructions are placed in step 4 because step 3 could have changed their offsets, but then after step 4, couldn't also again the offsets have changed for the target addresses from 3 again in some corner cases (given emit_a64_mov_i() is used also in jump encoding)? > Tested with test_bpf.ko and some arm64 working selftests, nothing failed. > > Signed-off-by: Xu Kuohai > --- > arch/arm64/net/bpf_jit_comp.c | 71 ++++++++++++++++++++++++++++------- > 1 file changed, 58 insertions(+), 13 deletions(-) > > diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c > index 30f76178608b..06437e34614b 100644 > --- a/arch/arm64/net/bpf_jit_comp.c > +++ b/arch/arm64/net/bpf_jit_comp.c > @@ -72,6 +72,7 @@ static const int bpf2a64[] = { > struct jit_ctx { > const struct bpf_prog *prog; > int idx; > + bool write; > int epilogue_offset; > int *offset; > int exentry_idx; > @@ -91,7 +92,7 @@ struct bpf_plt { > > static inline void emit(const u32 insn, struct jit_ctx *ctx) > { > - if (ctx->image != NULL) > + if (ctx->image != NULL && ctx->write) > ctx->image[ctx->idx] = cpu_to_le32(insn); > > ctx->idx++; > @@ -178,10 +179,29 @@ static inline void emit_addr_mov_i64(const int reg, const u64 val, > > static inline void emit_call(u64 target, struct jit_ctx *ctx) > { > - u8 tmp = bpf2a64[TMP_REG_1]; > + u8 tmp; > + long offset; > + unsigned long pc; > + u32 insn = AARCH64_BREAK_FAULT; > + > + /* if ctx->image == NULL or target == 0, the jump distance is unknown, > + * emit indirect call. > + */ > + if (ctx->image && target) { > + pc = (unsigned long)&ctx->image[ctx->idx]; > + offset = (long)target - (long)pc; > + if (offset >= -SZ_128M && offset < SZ_128M) > + insn = aarch64_insn_gen_branch_imm(pc, target, > + AARCH64_INSN_BRANCH_LINK); > + } > > - emit_addr_mov_i64(tmp, target, ctx); > - emit(A64_BLR(tmp), ctx); > + if (insn == AARCH64_BREAK_FAULT) { > + tmp = bpf2a64[TMP_REG_1]; > + emit_addr_mov_i64(tmp, target, ctx); > + emit(A64_BLR(tmp), ctx); > + } else { > + emit(insn, ctx); > + } > } > > static inline int bpf2a64_offset(int bpf_insn, int off, > @@ -1392,13 +1412,11 @@ static int build_body(struct jit_ctx *ctx, bool extra_pass) > const struct bpf_insn *insn = &prog->insnsi[i]; > int ret; > > - if (ctx->image == NULL) > - ctx->offset[i] = ctx->idx; > + ctx->offset[i] = ctx->idx; > ret = build_insn(insn, ctx, extra_pass); > if (ret > 0) { > i++; > - if (ctx->image == NULL) > - ctx->offset[i] = ctx->idx; > + ctx->offset[i] = ctx->idx; > continue; > } > if (ret) > @@ -1409,8 +1427,7 @@ static int build_body(struct jit_ctx *ctx, bool extra_pass) > * the last element with the offset after the last > * instruction (end of program) > */ > - if (ctx->image == NULL) > - ctx->offset[i] = ctx->idx; > + ctx->offset[i] = ctx->idx; > > return 0; > } > @@ -1461,6 +1478,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) > bool extra_pass = false; > struct jit_ctx ctx; > u8 *image_ptr; > + int body_idx; > + int exentry_idx; > > if (!prog->jit_requested) > return orig_prog; > @@ -1515,6 +1534,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) > goto out_off; > } > > + /* Get the max image size */ > if (build_body(&ctx, extra_pass)) { > prog = orig_prog; > goto out_off; > @@ -1528,7 +1548,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) > extable_size = prog->aux->num_exentries * > sizeof(struct exception_table_entry); > > - /* Now we know the actual image size. */ > + /* Now we know the max image size. */ > prog_size = sizeof(u32) * ctx.idx; > /* also allocate space for plt target */ > extable_offset = round_up(prog_size + PLT_TARGET_SIZE, extable_align); > @@ -1548,15 +1568,37 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) > skip_init_ctx: > ctx.idx = 0; > ctx.exentry_idx = 0; > + ctx.write = true; > > build_prologue(&ctx, was_classic); > > + /* Record exentry_idx and ctx.idx before first build_body */ > + exentry_idx = ctx.exentry_idx; > + body_idx = ctx.idx; > + /* Don't write instruction to memory for now */ > + ctx.write = false; > + > + /* Determine call distance and instruction position */ > if (build_body(&ctx, extra_pass)) { > bpf_jit_binary_free(header); > prog = orig_prog; > goto out_off; > } > > + ctx.epilogue_offset = ctx.idx; > + > + ctx.exentry_idx = exentry_idx; > + ctx.idx = body_idx; > + ctx.write = true; > + > + /* Determine jump offset and write result to memory */ > + if (build_body(&ctx, extra_pass) || > + WARN_ON_ONCE(ctx.idx != ctx.epilogue_offset)) { > + bpf_jit_binary_free(header); > + prog = orig_prog; > + goto out_off; > + } > + > build_epilogue(&ctx); > build_plt(&ctx); > > @@ -1567,6 +1609,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) > goto out_off; > } > > + /* Update prog size */ > + prog_size = sizeof(u32) * ctx.idx; > /* And we're done. */ > if (bpf_jit_enable > 1) > bpf_jit_dump(prog->len, prog_size, 2, ctx.image); > @@ -1574,8 +1618,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) > bpf_flush_icache(header, ctx.image + ctx.idx); > > if (!prog->is_func || extra_pass) { > - if (extra_pass && ctx.idx != jit_data->ctx.idx) { > - pr_err_once("multi-func JIT bug %d != %d\n", > + if (extra_pass && ctx.idx > jit_data->ctx.idx) { > + pr_err_once("multi-func JIT bug %d > %d\n", > ctx.idx, jit_data->ctx.idx); > bpf_jit_binary_free(header); > prog->bpf_func = NULL; > @@ -1976,6 +2020,7 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, > struct jit_ctx ctx = { > .image = NULL, > .idx = 0, > + .write = true, > }; > > /* the first 8 arguments are passed by registers */ > _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel