From: KaFai Wan <kafai.wan@linux.dev>
To: Tiezhu Yang <yangtiezhu@loongson.cn>, sashiko-reviews@lists.linux.dev
Cc: bpf@vger.kernel.org, Alexei Starovoitov <ast@kernel.org>
Subject: Re: [PATCH bpf-next v7 1/2] bpf: Introduce jit_required flag and refactor kfunc path
Date: Fri, 03 Jul 2026 21:51:29 +0800 [thread overview]
Message-ID: <4a0ac2692d2a76ab0479c2bf20dbf26a17636d67.camel@linux.dev> (raw)
In-Reply-To: <7cce1695-eaa2-816b-2877-9cb2f117aa27@loongson.cn>
On Fri, 2026-07-03 at 10:57 +0800, Tiezhu Yang wrote:
> On 2026/7/2 下午10:58, sashiko-bot@kernel.org wrote:
> > Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> > - [Medium] The `bpf_fixup_call_args()` function and `bpf_prog_has_kfunc_call()` macro were not
> > updated to use the new `jit_required` flag, leading to inconsistent interpreter fallback
> > behavior for pruned kfuncs.
> > --
> >
> > commit 5a3f8861c2b6916fe194f97a407cb7265f545fd0
> > Author: Tiezhu Yang <yangtiezhu@loongson.cn>
> >
> > bpf: Introduce jit_required flag and refactor kfunc path
> >
> > Introduce a 'jit_required' bitfield flag at the end of the
> > flags group in struct bpf_prog. This bit tracks whether a
> > program strictly requires the JIT compiler.
> >
> > > diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> > > index 649cce41e13f3..5fcd19ccb41a9 100644
> > > --- 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;
> > >
> > > if (!bpf_prog_select_interpreter(fp))
> >
> > [Severity: Medium]
> > Since bpf_prog_has_kfunc_call() was replaced here with fp->jit_required,
> > should bpf_fixup_call_args() in kernel/bpf/fixups.c also be updated to use
> > the new flag?
> >
> > Currently, bpf_fixup_call_args() still calls bpf_prog_has_kfunc_call(). If
> > a program has a pruned kfunc (allocating kfunc_tab but leaving
> > jit_required=0) and JIT falls back to the interpreter, wouldn't
> > bpf_fixup_call_args() incorrectly reject the program with -EINVAL?
> >
> > kernel/bpf/fixups.c:bpf_fixup_call_args() {
> > ...
> > bool has_kfunc_call = bpf_prog_has_kfunc_call(prog);
> > ...
> > if (has_kfunc_call) {
> > verbose(env, "calling kernel functions are not allowed in non-JITed
> > programs\n");
> > return -EINVAL;
> > }
> > ...
> > }
> >
> > Should bpf_prog_has_kfunc_call() in kernel/bpf/verifier.c be updated to
> > check prog->jit_required, or removed entirely in favor of checking the flag
> > directly?
>
> I think it is wrong to remove bpf_prog_has_kfunc_call() entirely,
I think it is ok to remove bpf_prog_has_kfunc_call() but with some changes. see below.
> because using prog->jit_required directly in bpf_fixup_call_args()
> would cause false positives.
>
> I tested the following changes:
>
> ```
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index 4e2b059d71f3..3a2fc194e2bb 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -3171,7 +3171,6 @@ const struct bpf_func_proto
> *bpf_base_func_proto(enum bpf_func_id func_id,
> const struct bpf_prog
> *prog);
> void bpf_task_storage_free(struct task_struct *task);
> void bpf_cgrp_storage_free(struct cgroup *cgroup);
> -bool bpf_prog_has_kfunc_call(const struct bpf_prog *prog);
> const struct btf_func_model *
> bpf_jit_find_kfunc_model(const struct bpf_prog *prog,
> const struct bpf_insn *insn);
> @@ -3510,11 +3509,6 @@ static inline void bpf_task_storage_free(struct
> task_struct *task)
> {
> }
>
> -static inline bool bpf_prog_has_kfunc_call(const struct bpf_prog *prog)
> -{
> - return false;
> -}
> -
> static inline const struct btf_func_model *
> bpf_jit_find_kfunc_model(const struct bpf_prog *prog,
> const struct bpf_insn *insn)
> diff --git a/kernel/bpf/fixups.c b/kernel/bpf/fixups.c
> index 94e0457a0aa3..7fb92b5fa415 100644
> --- a/kernel/bpf/fixups.c
> +++ b/kernel/bpf/fixups.c
> @@ -1378,7 +1378,6 @@ int bpf_fixup_call_args(struct bpf_verifier_env *env)
> #ifndef CONFIG_BPF_JIT_ALWAYS_ON
> struct bpf_prog *prog = env->prog;
> struct bpf_insn *insn = prog->insnsi;
> - bool has_kfunc_call = bpf_prog_has_kfunc_call(prog);
> int depth;
> #endif
> int i, err = 0;
> @@ -1404,7 +1403,7 @@ int bpf_fixup_call_args(struct bpf_verifier_env *env)
> return err;
> }
> #ifndef CONFIG_BPF_JIT_ALWAYS_ON
> - if (has_kfunc_call) {
> + if (prog->jit_required) {
> verbose(env, "calling kernel functions are not allowed
> in non-JITed programs\n");
we can change the log for general purpose. patch #2 and future case will hit this too.
> return -EINVAL;
> }
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index f496b45b9da4..3dbed3047254 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -2770,11 +2770,6 @@ int bpf_add_kfunc_call(struct bpf_verifier_env
> *env, u32 func_id, u16 offset)
> return 0;
> }
>
> -bool bpf_prog_has_kfunc_call(const struct bpf_prog *prog)
> -{
> - return !!prog->aux->kfunc_tab;
> -}
> -
> static int add_subprog_and_kfunc(struct bpf_verifier_env *env)
> {
> struct bpf_subprog_info *subprog = env->subprog_info;
> ```
>
> Here is the local test log:
>
> ```
> fedora@linux:~$ cat test_panic.c
> #include <linux/bpf.h>
> #include <bpf/bpf_helpers.h>
>
> SEC("kprobe/sys_getpid")
> int test_panic(void *ctx)
> {
> struct task_struct *task;
>
> task = (struct task_struct *)bpf_get_current_task();
> if (task)
> bpf_printk("Task address: %p\n", task);
>
> return 0;
> }
>
> char LICENSE[] SEC("license") = "GPL";
> fedora@linux:~$ clang -target bpf -O2 -g -c test_panic.c -o test_panic.o
> fedora@linux:~$ sudo sysctl -w net.core.bpf_jit_enable=0
> [sudo] password for fedora:
> net.core.bpf_jit_enable = 0
> fedora@linux:~$ sudo bpftool prog load test_panic.o
> /sys/fs/bpf/test_panic autoattach
> libbpf: prog 'test_panic': BPF program load failed: Invalid argument
> libbpf: prog 'test_panic': -- BEGIN PROG LOAD LOG --
> calling kernel functions are not allowed in non-JITed programs
> processed 10 insns (limit 1000000) max_states_per_insn 0 total_states 1
> peak_states 1 mark_read 0
> -- END PROG LOAD LOG --
> libbpf: prog 'test_panic': failed to load: -22
> libbpf: failed to load object 'test_panic.o'
> Error: failed to load object file
> ```
>
> This change incorrectly rejects programs that only contain normal
> inlined helper calls with -EINVAL.
Was it tested after compiling together with patch #2? seems patch #2 works.
>
> Instead, I think bpf_prog_has_kfunc_call() should be updated to check
> prog->jit_required, like so:
>
> ```
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index f496b45b9da4..1f5824c1c691 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -2772,7 +2772,7 @@ int bpf_add_kfunc_call(struct bpf_verifier_env
> *env, u32 func_id, u16 offset)
>
> bool bpf_prog_has_kfunc_call(const struct bpf_prog *prog)
> {
> - return !!prog->aux->kfunc_tab;
> + return prog->jit_required && !!prog->aux->kfunc_tab;
bpf_get_current_task() is a helper, not kfunc. test_panic has no kfunc, prog->aux->kfunc_tab
is null. so we get -ENOTSUPP(-524)
> }
>
> static int add_subprog_and_kfunc(struct bpf_verifier_env *env)
> ```
>
> Here is the local test log:
>
> ```
> fedora@linux:~$ cat test_panic.c
> #include <linux/bpf.h>
> #include <bpf/bpf_helpers.h>
>
> SEC("kprobe/sys_getpid")
> int test_panic(void *ctx)
> {
> struct task_struct *task;
>
> task = (struct task_struct *)bpf_get_current_task();
> if (task)
> bpf_printk("Task address: %p\n", task);
>
> return 0;
> }
>
> char LICENSE[] SEC("license") = "GPL";
> fedora@linux:~$ clang -target bpf -O2 -g -c test_panic.c -o test_panic.o
> fedora@linux:~$ sudo sysctl -w net.core.bpf_jit_enable=0
> [sudo] password for fedora:
> net.core.bpf_jit_enable = 0
> fedora@linux:~$ sudo bpftool prog load test_panic.o
> /sys/fs/bpf/test_panic autoattach
> libbpf: prog 'test_panic': BPF program load failed: unknown error (-524)
> libbpf: prog 'test_panic': -- BEGIN PROG LOAD LOG --
> processed 10 insns (limit 1000000) max_states_per_insn 0 total_states 1
> peak_states 1 mark_read 0
> -- END PROG LOAD LOG --
> libbpf: prog 'test_panic': failed to load: -524
> libbpf: failed to load object 'test_panic.o'
> Error: failed to load object file
> ```
>
> This ensures that pruned kfuncs (allocating kfunc_tab but leaving
> jit_required=0) safely return false, at the same time, this check
> perfectly isolates normal inlined helper paths.
pruned kfuncs well handled in patch [1], see details in check_kfunc_call() and fixup_kfunc_call().
[1] https://lore.kernel.org/bpf/20211002011757.311265-3-memxor@gmail.com/
>
> Let me wait for more review comments and will send v8 next week.
>
> Thanks,
> Tiezhu
>
--
Thanks,
KaFai
next prev parent reply other threads:[~2026-07-03 13:51 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-02 14:36 [PATCH bpf-next v7 0/2] Introduce jit_required to prevent a kernel panic Tiezhu Yang
2026-07-02 14:36 ` [PATCH bpf-next v7 1/2] bpf: Introduce jit_required flag and refactor kfunc path Tiezhu Yang
2026-07-02 14:58 ` sashiko-bot
2026-07-03 2:57 ` Tiezhu Yang
2026-07-03 5:24 ` Leon Hwang
2026-07-03 6:59 ` Tiezhu Yang
2026-07-03 14:14 ` Leon Hwang
2026-07-03 15:53 ` Tiezhu Yang
2026-07-04 1:17 ` KaFai Wan
2026-07-03 13:51 ` KaFai Wan [this message]
2026-07-03 15:56 ` Tiezhu Yang
2026-07-04 3:23 ` KaFai Wan
2026-07-03 13:55 ` KaFai Wan
2026-07-03 16:14 ` Tiezhu Yang
2026-07-04 1:57 ` KaFai Wan
2026-07-04 2:05 ` KaFai Wan
2026-07-02 14:36 ` [PATCH bpf-next v7 2/2] bpf: Reject programs with inlined helpers if JIT is unavailable Tiezhu Yang
2026-07-02 14:57 ` sashiko-bot
2026-07-03 4:14 ` 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=4a0ac2692d2a76ab0479c2bf20dbf26a17636d67.camel@linux.dev \
--to=kafai.wan@linux.dev \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=yangtiezhu@loongson.cn \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox