In following changes we will need to change ftrace direct attachment
logic. In order to do that adding struct bpf_trampoline_ops object
that defines 3 callbacks that follow ftrace attachment functions:

   register_fentry
   unregister_fentry
   modify_fentry

The new struct bpf_trampoline_ops object is passed as an argument to
__bpf_trampoline_link_prog function.

At the moment the default trampoline_ops is set to the current ftrace
direct attachment functions, so there's no change for current code.

Signed-off-by: Jiri Olsa <[email protected]>
---
 kernel/bpf/trampoline.c | 53 +++++++++++++++++++++++++++++------------
 1 file changed, 38 insertions(+), 15 deletions(-)

diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
index 952cd7932461..ec9c1db78f47 100644
--- a/kernel/bpf/trampoline.c
+++ b/kernel/bpf/trampoline.c
@@ -30,6 +30,13 @@ static struct hlist_head 
trampoline_ip_table[TRAMPOLINE_TABLE_SIZE];
 /* serializes access to trampoline tables */
 static DEFINE_MUTEX(trampoline_mutex);
 
+struct bpf_trampoline_ops {
+       int (*register_fentry)(struct bpf_trampoline *tr, void *new_addr, void 
*data);
+       int (*unregister_fentry)(struct bpf_trampoline *tr, u32 orig_flags, 
void *old_addr, void *data);
+       int (*modify_fentry)(struct bpf_trampoline *tr, u32 orig_flags, void 
*old_addr, void *new_addr,
+                            bool lock_direct_mutex, void *data);
+};
+
 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
 static int bpf_trampoline_update(struct bpf_trampoline *tr, bool 
lock_direct_mutex);
 
@@ -387,7 +394,7 @@ static int bpf_trampoline_update_fentry(struct 
bpf_trampoline *tr, u32 orig_flag
 }
 
 static int unregister_fentry(struct bpf_trampoline *tr, u32 orig_flags,
-                            void *old_addr)
+                            void *old_addr, void *data)
 {
        int ret;
 
@@ -401,7 +408,7 @@ static int unregister_fentry(struct bpf_trampoline *tr, u32 
orig_flags,
 
 static int modify_fentry(struct bpf_trampoline *tr, u32 orig_flags,
                         void *old_addr, void *new_addr,
-                        bool lock_direct_mutex)
+                        bool lock_direct_mutex, void *data __maybe_unused)
 {
        int ret;
 
@@ -415,7 +422,7 @@ static int modify_fentry(struct bpf_trampoline *tr, u32 
orig_flags,
 }
 
 /* first time registering */
-static int register_fentry(struct bpf_trampoline *tr, void *new_addr)
+static int register_fentry(struct bpf_trampoline *tr, void *new_addr, void 
*data __maybe_unused)
 {
        void *ip = tr->func.addr;
        unsigned long faddr;
@@ -437,6 +444,12 @@ static int register_fentry(struct bpf_trampoline *tr, void 
*new_addr)
        return ret;
 }
 
+static struct bpf_trampoline_ops trampoline_ops = {
+       .register_fentry   = register_fentry,
+       .unregister_fentry = unregister_fentry,
+       .modify_fentry     = modify_fentry,
+};
+
 static struct bpf_tramp_links *
 bpf_trampoline_get_progs(const struct bpf_trampoline *tr, int *total, bool 
*ip_arg)
 {
@@ -604,7 +617,8 @@ 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_ops(struct bpf_trampoline *tr, bool 
lock_direct_mutex,
+                                    struct bpf_trampoline_ops *ops, void *data)
 {
        struct bpf_tramp_image *im;
        struct bpf_tramp_links *tlinks;
@@ -617,7 +631,7 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, 
bool lock_direct_mut
                return PTR_ERR(tlinks);
 
        if (total == 0) {
-               err = unregister_fentry(tr, orig_flags, tr->cur_image->image);
+               err = ops->unregister_fentry(tr, orig_flags, 
tr->cur_image->image, data);
                bpf_tramp_image_put(tr->cur_image);
                tr->cur_image = NULL;
                goto out;
@@ -688,11 +702,11 @@ static int bpf_trampoline_update(struct bpf_trampoline 
*tr, bool lock_direct_mut
        WARN_ON(tr->cur_image && total == 0);
        if (tr->cur_image)
                /* progs already running at this address */
-               err = modify_fentry(tr, orig_flags, tr->cur_image->image,
-                                   im->image, lock_direct_mutex);
+               err = ops->modify_fentry(tr, orig_flags, tr->cur_image->image,
+                                        im->image, lock_direct_mutex, data);
        else
                /* first time registering */
-               err = register_fentry(tr, im->image);
+               err = ops->register_fentry(tr, im->image, data);
 
 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
        if (err == -EAGAIN) {
@@ -722,6 +736,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_ops(tr, lock_direct_mutex, 
&trampoline_ops, NULL);
+}
+
 static enum bpf_tramp_prog_type bpf_attach_type_to_tramp(struct bpf_prog *prog)
 {
        switch (prog->expected_attach_type) {
@@ -766,7 +785,9 @@ static int bpf_freplace_check_tgt_prog(struct bpf_prog 
*tgt_prog)
 
 static int __bpf_trampoline_link_prog(struct bpf_tramp_link *link,
                                      struct bpf_trampoline *tr,
-                                     struct bpf_prog *tgt_prog)
+                                     struct bpf_prog *tgt_prog,
+                                     struct bpf_trampoline_ops *ops,
+                                     void *data)
 {
        struct bpf_fsession_link *fslink = NULL;
        enum bpf_tramp_prog_type kind;
@@ -824,7 +845,7 @@ static int __bpf_trampoline_link_prog(struct bpf_tramp_link 
*link,
        } else {
                tr->progs_cnt[kind]++;
        }
-       err = bpf_trampoline_update(tr, true /* lock_direct_mutex */);
+       err = bpf_trampoline_update_ops(tr, true /* lock_direct_mutex */, ops, 
data);
        if (err) {
                hlist_del_init(&link->tramp_hlist);
                if (kind == BPF_TRAMP_FSESSION) {
@@ -845,14 +866,16 @@ int bpf_trampoline_link_prog(struct bpf_tramp_link *link,
        int err;
 
        mutex_lock(&tr->mutex);
-       err = __bpf_trampoline_link_prog(link, tr, tgt_prog);
+       err = __bpf_trampoline_link_prog(link, tr, tgt_prog, &trampoline_ops, 
NULL);
        mutex_unlock(&tr->mutex);
        return err;
 }
 
 static int __bpf_trampoline_unlink_prog(struct bpf_tramp_link *link,
                                        struct bpf_trampoline *tr,
-                                       struct bpf_prog *tgt_prog)
+                                       struct bpf_prog *tgt_prog,
+                                       struct bpf_trampoline_ops *ops,
+                                       void *data)
 {
        enum bpf_tramp_prog_type kind;
        int err;
@@ -877,7 +900,7 @@ static int __bpf_trampoline_unlink_prog(struct 
bpf_tramp_link *link,
        }
        hlist_del_init(&link->tramp_hlist);
        tr->progs_cnt[kind]--;
-       return bpf_trampoline_update(tr, true /* lock_direct_mutex */);
+       return bpf_trampoline_update_ops(tr, true /* lock_direct_mutex */, ops, 
data);
 }
 
 /* bpf_trampoline_unlink_prog() should never fail. */
@@ -888,7 +911,7 @@ int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link,
        int err;
 
        mutex_lock(&tr->mutex);
-       err = __bpf_trampoline_unlink_prog(link, tr, tgt_prog);
+       err = __bpf_trampoline_unlink_prog(link, tr, tgt_prog, &trampoline_ops, 
NULL);
        mutex_unlock(&tr->mutex);
        return err;
 }
@@ -1019,7 +1042,7 @@ int bpf_trampoline_link_cgroup_shim(struct bpf_prog *prog,
                goto err;
        }
 
-       err = __bpf_trampoline_link_prog(&shim_link->link, tr, NULL);
+       err = __bpf_trampoline_link_prog(&shim_link->link, tr, NULL, 
&trampoline_ops, NULL);
        if (err)
                goto err;
 
-- 
2.52.0


Reply via email to