From: KaFai Wan <kafai.wan@linux.dev>
To: Tiezhu Yang <yangtiezhu@loongson.cn>,
Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>,
Eduard Zingerman <eddyz87@gmail.com>,
Kumar Kartikeya Dwivedi <memxor@gmail.com>,
Martin KaFai Lau <martin.lau@linux.dev>,
Song Liu <song@kernel.org>,
Yonghong Song <yonghong.song@linux.dev>,
Jiri Olsa <jolsa@kernel.org>,
Emil Tsalapatis <emil@etsalapatis.com>
Cc: bpf@vger.kernel.org, loongarch@lists.linux.dev,
"Leon Hwang" <leon.hwang@linux.dev>,
"Puranjay Mohan" <puranjay@kernel.org>,
"Björn Töpel" <bjorn@kernel.org>
Subject: Re: [PATCH bpf-next v6] bpf: Reject programs with inlined helpers if JIT is unavailable
Date: Thu, 02 Jul 2026 20:16:51 +0800 [thread overview]
Message-ID: <f61c41783f56fc259b56141e8d438a56c9dfa31b.camel@linux.dev> (raw)
In-Reply-To: <20260702053127.23599-1-yangtiezhu@loongson.cn>
On Thu, 2026-07-02 at 13:31 +0800, Tiezhu Yang wrote:
> When an architecture implements bpf_jit_inlines_helper_call(), such as
> LoongArch, ARM64, PowerPC, and RISC-V, the verifier skips rewriting the
> helper call offset (insn->imm) during the bpf_do_misc_fixups() phase,
> because the helper is expected to be inlined by the JIT compiler. As a
> result, insn->imm remains as the raw helper enum ID.
>
> However, if JIT is disabled at runtime (net.core.bpf_jit_enable=0) or
> if the JIT compilation later dynamically fails (e.g., due to OOM), the
> core BPF subsystem falls back to the BPF interpreter.
>
> When the interpreter executes (__bpf_call_base + insn->imm) with the
> unpatched raw helper ID, it jumps into an unaligned invalid address
> space, triggering an instruction alignment fault or a memory access
> panic.
>
> To avoid modifying the BPF interpreter's complexity for JIT-specific
> paths, just introduce a 'jit_required' flag in struct bpf_prog. When
> a program contains helper calls that skip rewriting for JIT inlining,
> set this flag to 1. During runtime selection, if JIT compilation is
> not available, explicitly reject loading with -ENOTSUPP instead of
> falling back to the interpreter, safely preventing the kernel panic.
>
> Fixes: 2ddec2c80b44 ("riscv, bpf: inline bpf_get_smp_processor_id()")
> Suggested-by: Alexei Starovoitov <ast@kernel.org>
> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
> ---
> v6:
> - Place 'jit_required' as a standalone u8 field right before 'stats'
> to reuse the existing 4-byte struct hole (offset 52) based on pahole
> analysis, avoiding the u16->u32 bitfield conversion in v5 which
> unintentionally changed the layout/alignment of subsequent fields.
>
> v5:
> - Drop the fallback interpreter fixups as per maintainer's feedback.
> - Introduce 'jit_required' member in struct bpf_prog to flag programs
> that strictly rely on JIT.
> - Reject loading with -ENOTSUPP in __bpf_prog_select_runtime() if JIT
> fails or is disabled for these programs.
> - Upgrade 'jited' bitfield group type from u16 to u32 in struct bpf_prog
> to prevent 17-bit overflow warning.
>
> include/linux/bpf.h | 1 +
> kernel/bpf/core.c | 2 +-
> kernel/bpf/fixups.c | 4 +++-
> 3 files changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index ba09795e0bfd..f5c283af3cf7 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -1889,6 +1889,7 @@ struct bpf_prog {
> u8 digest[SHA256_DIGEST_SIZE];
> u8 tag[BPF_TAG_SIZE];
> };
> + u8 jit_required; /* program strictly requires JIT compiler */
maybe 1 bit is enough. I'm not sure the layout matters, if not we can put behind sleepable:1.
> struct bpf_prog_stats __percpu *stats;
> u8 __percpu *active; /* u8[BPF_NR_CONTEXTS] for recursion protection
> */
> unsigned int (*bpf_func)(const void *ctx,
> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> index 649cce41e13f..a55754bcc593 100644
> --- a/kernel/bpf/core.c
> +++ b/kernel/bpf/core.c
> @@ -2639,7 +2639,7 @@ struct bpf_prog *__bpf_prog_select_runtime(struct bpf_verifier_env *env,
> struct
>
> fp = bpf_prog_jit_compile(env, fp);
> bpf_prog_jit_attempt_done(fp);
> - if (!fp->jited && jit_needed) {
> + if (!fp->jited && (jit_needed || fp->jit_required)) {
You ignore Alexei's feedback. Should be
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -2619,8 +2619,7 @@ struct bpf_prog *__bpf_prog_select_runtime(struct bpf_verifier_env *env,
struct
if (fp->bpf_func)
goto finalize;
- if (IS_ENABLED(CONFIG_BPF_JIT_ALWAYS_ON) ||
- bpf_prog_has_kfunc_call(fp))
+ if (IS_ENABLED(CONFIG_BPF_JIT_ALWAYS_ON) || fp->jit_required)
jit_needed = true;
so we can set fp->jit_required when need, without change the rest.
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 25aea4271cd0..3b2fb0163db7 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -2712,6 +2712,7 @@ int bpf_add_kfunc_call(struct bpf_verifier_env *env, u32 func_id, u16 offset)
if (!tab)
return -ENOMEM;
prog_aux->kfunc_tab = tab;
+ env->prog->jit_required = true;
}
So the patch#1 is a refactor, some sort of this, I'm not sure it's right.
> *err = -ENOTSUPP;
> return fp;
> }
> diff --git a/kernel/bpf/fixups.c b/kernel/bpf/fixups.c
> index 12a8a4eb757f..94e0457a0aa3 100644
> --- a/kernel/bpf/fixups.c
> +++ b/kernel/bpf/fixups.c
> @@ -1841,8 +1841,10 @@ int bpf_do_misc_fixups(struct bpf_verifier_env *env)
> }
>
> /* Skip inlining the helper call if the JIT does it. */
> - if (bpf_jit_inlines_helper_call(insn->imm))
> + if (bpf_jit_inlines_helper_call(insn->imm)) {
> + prog->jit_required = 1;
This's the patch#2.
> goto next_insn;
> + }
>
> if (insn->imm == BPF_FUNC_get_route_realm)
> prog->dst_needed = 1;
and the rest.
--
Thanks,
KaFai
next prev parent reply other threads:[~2026-07-02 12:17 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-02 5:31 [PATCH bpf-next v6] bpf: Reject programs with inlined helpers if JIT is unavailable Tiezhu Yang
2026-07-02 5:45 ` Alexei Starovoitov
2026-07-02 6:10 ` Tiezhu Yang
2026-07-02 7:20 ` Tiezhu Yang
2026-07-02 6:01 ` bot+bpf-ci
2026-07-02 12:16 ` KaFai Wan [this message]
2026-07-02 14:38 ` Tiezhu Yang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=f61c41783f56fc259b56141e8d438a56c9dfa31b.camel@linux.dev \
--to=kafai.wan@linux.dev \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bjorn@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=emil@etsalapatis.com \
--cc=jolsa@kernel.org \
--cc=leon.hwang@linux.dev \
--cc=loongarch@lists.linux.dev \
--cc=martin.lau@linux.dev \
--cc=memxor@gmail.com \
--cc=puranjay@kernel.org \
--cc=song@kernel.org \
--cc=yangtiezhu@loongson.cn \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.