In following changes we will need to override ftrace direct attachment
behaviour. In order to do that we are adding struct bpf_trampoline_ops
object that defines callbacks for ftrace direct attachment:

   register_fentry
   unregister_fentry
   modify_fentry

The new struct bpf_trampoline_ops object is passed as an argument to
__bpf_trampoline_link/unlink_prog functions.

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

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

diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
index 05dc0358654d..e9f0152289a4 100644
--- a/kernel/bpf/trampoline.c
+++ b/kernel/bpf/trampoline.c
@@ -69,6 +69,14 @@ static int __init trampoline_locks_init(void)
        return 0;
 }
 
+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);
 
@@ -425,7 +433,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;
 
@@ -439,7 +447,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;
 
@@ -453,7 +461,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;
@@ -475,6 +483,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)
 {
@@ -642,7 +656,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;
@@ -655,7 +670,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;
@@ -726,11 +741,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) {
@@ -760,6 +775,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) {
@@ -804,7 +824,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;
@@ -862,7 +884,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) {
@@ -883,14 +905,16 @@ int bpf_trampoline_link_prog(struct bpf_tramp_link *link,
        int err;
 
        trampoline_lock(tr);
-       err = __bpf_trampoline_link_prog(link, tr, tgt_prog);
+       err = __bpf_trampoline_link_prog(link, tr, tgt_prog, &trampoline_ops, 
NULL);
        trampoline_unlock(tr);
        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;
@@ -915,7 +939,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. */
@@ -926,7 +950,7 @@ int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link,
        int err;
 
        trampoline_lock(tr);
-       err = __bpf_trampoline_unlink_prog(link, tr, tgt_prog);
+       err = __bpf_trampoline_unlink_prog(link, tr, tgt_prog, &trampoline_ops, 
NULL);
        trampoline_unlock(tr);
        return err;
 }
@@ -1058,7 +1082,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