bpf: add bpf_func_t and trampoline helpers
authorStanislav Fomichev <sdf@google.com>
Tue, 28 Jun 2022 17:43:04 +0000 (10:43 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 29 Jun 2022 20:21:51 +0000 (13:21 -0700)
I'll be adding lsm cgroup specific helpers that grab
trampoline mutex.

No functional changes.

Reviewed-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Stanislav Fomichev <sdf@google.com>
Link: https://lore.kernel.org/r/20220628174314.1216643-2-sdf@google.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
include/linux/bpf.h
kernel/bpf/trampoline.c

index d05e149..d547be9 100644 (file)
@@ -56,6 +56,8 @@ typedef u64 (*bpf_callback_t)(u64, u64, u64, u64, u64);
 typedef int (*bpf_iter_init_seq_priv_t)(void *private_data,
                                        struct bpf_iter_aux_info *aux);
 typedef void (*bpf_iter_fini_seq_priv_t)(void *private_data);
+typedef unsigned int (*bpf_func_t)(const void *,
+                                  const struct bpf_insn *);
 struct bpf_iter_seq_info {
        const struct seq_operations *seq_ops;
        bpf_iter_init_seq_priv_t init_seq_private;
@@ -879,8 +881,7 @@ struct bpf_dispatcher {
 static __always_inline __nocfi unsigned int bpf_dispatcher_nop_func(
        const void *ctx,
        const struct bpf_insn *insnsi,
-       unsigned int (*bpf_func)(const void *,
-                                const struct bpf_insn *))
+       bpf_func_t bpf_func)
 {
        return bpf_func(ctx, insnsi);
 }
@@ -909,8 +910,7 @@ int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs);
        noinline __nocfi unsigned int bpf_dispatcher_##name##_func(     \
                const void *ctx,                                        \
                const struct bpf_insn *insnsi,                          \
-               unsigned int (*bpf_func)(const void *,                  \
-                                        const struct bpf_insn *))      \
+               bpf_func_t bpf_func)                                    \
        {                                                               \
                return bpf_func(ctx, insnsi);                           \
        }                                                               \
@@ -921,8 +921,7 @@ int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs);
        unsigned int bpf_dispatcher_##name##_func(                      \
                const void *ctx,                                        \
                const struct bpf_insn *insnsi,                          \
-               unsigned int (*bpf_func)(const void *,                  \
-                                        const struct bpf_insn *));     \
+               bpf_func_t bpf_func);                                   \
        extern struct bpf_dispatcher bpf_dispatcher_##name;
 #define BPF_DISPATCHER_FUNC(name) bpf_dispatcher_##name##_func
 #define BPF_DISPATCHER_PTR(name) (&bpf_dispatcher_##name)
index 93c7675..5466e15 100644 (file)
@@ -410,7 +410,7 @@ static enum bpf_tramp_prog_type bpf_attach_type_to_tramp(struct bpf_prog *prog)
        }
 }
 
-int bpf_trampoline_link_prog(struct bpf_tramp_link *link, struct bpf_trampoline *tr)
+static int __bpf_trampoline_link_prog(struct bpf_tramp_link *link, struct bpf_trampoline *tr)
 {
        enum bpf_tramp_prog_type kind;
        struct bpf_tramp_link *link_exiting;
@@ -418,44 +418,33 @@ int bpf_trampoline_link_prog(struct bpf_tramp_link *link, struct bpf_trampoline
        int cnt = 0, i;
 
        kind = bpf_attach_type_to_tramp(link->link.prog);
-       mutex_lock(&tr->mutex);
-       if (tr->extension_prog) {
+       if (tr->extension_prog)
                /* cannot attach fentry/fexit if extension prog is attached.
                 * cannot overwrite extension prog either.
                 */
-               err = -EBUSY;
-               goto out;
-       }
+               return -EBUSY;
 
        for (i = 0; i < BPF_TRAMP_MAX; i++)
                cnt += tr->progs_cnt[i];
 
        if (kind == BPF_TRAMP_REPLACE) {
                /* Cannot attach extension if fentry/fexit are in use. */
-               if (cnt) {
-                       err = -EBUSY;
-                       goto out;
-               }
+               if (cnt)
+                       return -EBUSY;
                tr->extension_prog = link->link.prog;
-               err = bpf_arch_text_poke(tr->func.addr, BPF_MOD_JUMP, NULL,
-                                        link->link.prog->bpf_func);
-               goto out;
-       }
-       if (cnt >= BPF_MAX_TRAMP_LINKS) {
-               err = -E2BIG;
-               goto out;
+               return bpf_arch_text_poke(tr->func.addr, BPF_MOD_JUMP, NULL,
+                                         link->link.prog->bpf_func);
        }
-       if (!hlist_unhashed(&link->tramp_hlist)) {
+       if (cnt >= BPF_MAX_TRAMP_LINKS)
+               return -E2BIG;
+       if (!hlist_unhashed(&link->tramp_hlist))
                /* prog already linked */
-               err = -EBUSY;
-               goto out;
-       }
+               return -EBUSY;
        hlist_for_each_entry(link_exiting, &tr->progs_hlist[kind], tramp_hlist) {
                if (link_exiting->link.prog != link->link.prog)
                        continue;
                /* prog already linked */
-               err = -EBUSY;
-               goto out;
+               return -EBUSY;
        }
 
        hlist_add_head(&link->tramp_hlist, &tr->progs_hlist[kind]);
@@ -465,30 +454,44 @@ int bpf_trampoline_link_prog(struct bpf_tramp_link *link, struct bpf_trampoline
                hlist_del_init(&link->tramp_hlist);
                tr->progs_cnt[kind]--;
        }
-out:
+       return err;
+}
+
+int bpf_trampoline_link_prog(struct bpf_tramp_link *link, struct bpf_trampoline *tr)
+{
+       int err;
+
+       mutex_lock(&tr->mutex);
+       err = __bpf_trampoline_link_prog(link, tr);
        mutex_unlock(&tr->mutex);
        return err;
 }
 
-/* bpf_trampoline_unlink_prog() should never fail. */
-int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link, struct bpf_trampoline *tr)
+static int __bpf_trampoline_unlink_prog(struct bpf_tramp_link *link, struct bpf_trampoline *tr)
 {
        enum bpf_tramp_prog_type kind;
        int err;
 
        kind = bpf_attach_type_to_tramp(link->link.prog);
-       mutex_lock(&tr->mutex);
        if (kind == BPF_TRAMP_REPLACE) {
                WARN_ON_ONCE(!tr->extension_prog);
                err = bpf_arch_text_poke(tr->func.addr, BPF_MOD_JUMP,
                                         tr->extension_prog->bpf_func, NULL);
                tr->extension_prog = NULL;
-               goto out;
+               return err;
        }
        hlist_del_init(&link->tramp_hlist);
        tr->progs_cnt[kind]--;
-       err = bpf_trampoline_update(tr);
-out:
+       return bpf_trampoline_update(tr);
+}
+
+/* bpf_trampoline_unlink_prog() should never fail. */
+int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link, struct bpf_trampoline *tr)
+{
+       int err;
+
+       mutex_lock(&tr->mutex);
+       err = __bpf_trampoline_unlink_prog(link, tr);
        mutex_unlock(&tr->mutex);
        return err;
 }