[RFC PATCH bpf-next 3/7] bpf: Enable BPF_LINK_UPDATE for fentry/fexit/fmod_ret links
bot+bpf-ci at kernel.org
bot+bpf-ci at kernel.org
Mon Nov 17 17:19:33 PST 2025
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index 23fcbcd26..7daf40cbd 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -1215,6 +1215,8 @@ enum {
>
> struct bpf_tramp_links {
> struct bpf_tramp_link *links[BPF_MAX_TRAMP_LINKS];
> + struct bpf_tramp_link *update_link;
> + struct bpf_prog *update_prog;
> int nr_links;
> };
[ ... ]
> @@ -1840,6 +1843,13 @@ struct bpf_tramp_link {
> u64 cookie;
> };
>
> +static inline struct bpf_prog *
> +bpf_tramp_links_prog(struct bpf_tramp_links *tl, int i)
> +{
> + return tl->links[i] == tl->update_link ? tl->update_prog :
> + tl->links[i]->link.prog;
> +}
This helper is added but the architecture-specific code in
arch/x86/net/bpf_jit_comp.c, arch/arm64/net/bpf_jit_comp.c, and
arch/s390/net/bpf_jit_comp.c continues to access tl->links[i]->link.prog
directly. When __bpf_trampoline_update() passes tlinks with update_link
and update_prog set, won't arch_prepare_bpf_trampoline() and
arch_bpf_trampoline_size() use the old program instead of the new one?
For example, in arch/x86/net/bpf_jit_comp.c around line 2966:
struct bpf_prog *p = l->link.prog;
This should probably use bpf_tramp_links_prog() to get the correct
program during updates. The same pattern appears in the other arch
implementations.
> diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
> index 171440f37..486f945f6 100644
> --- a/kernel/bpf/trampoline.c
> +++ b/kernel/bpf/trampoline.c
> @@ -232,7 +232,10 @@ static int register_fentry(struct bpf_trampoline *tr, void *new_addr)
> }
>
> static struct bpf_tramp_links *
> -bpf_trampoline_get_progs(const struct bpf_trampoline *tr, int *total, bool *ip_arg)
> +bpf_trampoline_get_progs(const struct bpf_trampoline *tr,
> + struct bpf_tramp_link *update_link,
> + struct bpf_prog *update_prog,
> + int *total, bool *ip_arg)
> {
> struct bpf_tramp_link *link;
> struct bpf_tramp_links *tlinks;
> @@ -252,6 +255,11 @@ bpf_trampoline_get_progs(const struct bpf_trampoline *tr, int *total, bool *ip_a
> hlist_for_each_entry(link, &tr->progs_hlist[kind], tramp_hlist) {
> *ip_arg |= link->link.prog->call_get_func_ip;
> *links++ = link;
> + if (link == update_link) {
> + *ip_arg |= update_prog->call_get_func_ip;
> + tlinks[kind].update_link = update_link;
> + tlinks[kind].update_prog = update_prog;
> + }
> }
> }
> return tlinks;
[ ... ]
> @@ -397,7 +405,10 @@ static struct bpf_tramp_image *bpf_tramp_image_alloc(u64 key, int size)
> return ERR_PTR(err);
> }
>
> -static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mutex)
> +static int __bpf_trampoline_update(struct bpf_trampoline *tr,
> + struct bpf_tramp_link *update_link,
> + struct bpf_prog *update_prog,
> + bool lock_direct_mutex)
> {
> struct bpf_tramp_image *im;
> struct bpf_tramp_links *tlinks;
> @@ -405,7 +416,11 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mut
> bool ip_arg = false;
> int err, total, size;
>
> - tlinks = bpf_trampoline_get_progs(tr, &total, &ip_arg);
> + if (update_link && !bpf_trampoline_supports_update_prog())
> + return -ENOTSUPP;
> +
> + tlinks = bpf_trampoline_get_progs(tr, update_link, update_prog,
> + &total, &ip_arg);
[ ... ]
> @@ -503,6 +518,11 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mut
> goto out;
> }
>
> +static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mutex)
> +{
> + return __bpf_trampoline_update(tr, NULL, NULL, lock_direct_mutex);
> +}
> +
> static enum bpf_tramp_prog_type bpf_attach_type_to_tramp(struct bpf_prog *prog)
> {
> switch (prog->expected_attach_type) {
> @@ -626,7 +646,7 @@ static int __bpf_trampoline_update_prog(struct bpf_tramp_link *link,
> return 0;
> }
>
> - return -ENOTSUPP;
> + return __bpf_trampoline_update(tr, link, new_prog, true);
> }
[ ... ]
> @@ -1136,6 +1156,11 @@ arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *image
> return -ENOTSUPP;
> }
>
> +bool __weak bpf_trampoline_supports_update_prog(void)
> +{
> + return false;
> +}
The commit message says "For now, only x86, arm64, and s390 are
implemented" but none of these architectures appear to be updated in
this patch or in the visible preceding commits (627b0f207, b0184022d).
Without overriding bpf_trampoline_supports_update_prog() to return true
and updating the arch code to use bpf_tramp_links_prog(), the feature
will always return -ENOTSUPP on all architectures. Was this patch meant
to include the arch-specific implementations, or are they in a separate
series?
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/19450205468
More information about the linux-arm-kernel
mailing list