In preparation to use raw tracepoints for BPF directly from ftrace, move
the bpf_raw_tracepoint functionality into bpf_trace.c

Signed-off-by: Joel Fernandes (Google) <j...@joelfernandes.org>
---
 include/linux/bpf_trace.h   | 10 ++++++
 kernel/bpf/syscall.c        | 69 ++++++-------------------------------
 kernel/trace/bpf_trace.c    | 56 ++++++++++++++++++++++++++++++
 kernel/trace/trace_events.c |  3 ++
 4 files changed, 80 insertions(+), 58 deletions(-)

diff --git a/include/linux/bpf_trace.h b/include/linux/bpf_trace.h
index ddf896abcfb6..4a593827fd87 100644
--- a/include/linux/bpf_trace.h
+++ b/include/linux/bpf_trace.h
@@ -4,4 +4,14 @@
 
 #include <trace/events/xdp.h>
 
+#define BPF_RAW_TRACEPOINT_OPEN_LAST_FIELD raw_tracepoint.prog_fd
+
+struct bpf_raw_tracepoint {
+       struct bpf_raw_event_map *btp;
+       struct bpf_prog *prog;
+};
+
+struct bpf_raw_tracepoint *bpf_raw_tracepoint_open(char *tp_name, int prog_fd);
+void bpf_raw_tracepoint_close(struct bpf_raw_tracepoint *tp);
+
 #endif /* __LINUX_BPF_TRACE_H__ */
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 42d17f730780..2001949b33f1 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -1737,21 +1737,11 @@ static int bpf_obj_get(const union bpf_attr *attr)
                                attr->file_flags);
 }
 
-struct bpf_raw_tracepoint {
-       struct bpf_raw_event_map *btp;
-       struct bpf_prog *prog;
-};
-
 static int bpf_raw_tracepoint_release(struct inode *inode, struct file *filp)
 {
        struct bpf_raw_tracepoint *raw_tp = filp->private_data;
 
-       if (raw_tp->prog) {
-               bpf_probe_unregister(raw_tp->btp, raw_tp->prog);
-               bpf_prog_put(raw_tp->prog);
-       }
-       bpf_put_raw_tracepoint(raw_tp->btp);
-       kfree(raw_tp);
+       bpf_raw_tracepoint_close(raw_tp);
        return 0;
 }
 
@@ -1761,64 +1751,27 @@ static const struct file_operations bpf_raw_tp_fops = {
        .write          = bpf_dummy_write,
 };
 
-#define BPF_RAW_TRACEPOINT_OPEN_LAST_FIELD raw_tracepoint.prog_fd
-
-static int bpf_raw_tracepoint_open(const union bpf_attr *attr)
+static int bpf_raw_tracepoint_open_syscall(const union bpf_attr *attr)
 {
-       struct bpf_raw_tracepoint *raw_tp;
-       struct bpf_raw_event_map *btp;
-       struct bpf_prog *prog;
+       int tp_fd;
        char tp_name[128];
-       int tp_fd, err;
+       struct bpf_raw_tracepoint *raw_tp;
 
        if (strncpy_from_user(tp_name, 
u64_to_user_ptr(attr->raw_tracepoint.name),
                              sizeof(tp_name) - 1) < 0)
                return -EFAULT;
        tp_name[sizeof(tp_name) - 1] = 0;
 
-       btp = bpf_get_raw_tracepoint(tp_name);
-       if (!btp)
-               return -ENOENT;
-
-       raw_tp = kzalloc(sizeof(*raw_tp), GFP_USER);
-       if (!raw_tp) {
-               err = -ENOMEM;
-               goto out_put_btp;
-       }
-       raw_tp->btp = btp;
-
-       prog = bpf_prog_get(attr->raw_tracepoint.prog_fd);
-       if (IS_ERR(prog)) {
-               err = PTR_ERR(prog);
-               goto out_free_tp;
-       }
-       if (prog->type != BPF_PROG_TYPE_RAW_TRACEPOINT &&
-           prog->type != BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE) {
-               err = -EINVAL;
-               goto out_put_prog;
-       }
-
-       err = bpf_probe_register(raw_tp->btp, prog);
-       if (err)
-               goto out_put_prog;
+       raw_tp = bpf_raw_tracepoint_open(tp_name, attr->raw_tracepoint.prog_fd);
+       if (IS_ERR(raw_tp))
+               return PTR_ERR(raw_tp);
 
-       raw_tp->prog = prog;
        tp_fd = anon_inode_getfd("bpf-raw-tracepoint", &bpf_raw_tp_fops, raw_tp,
                                 O_CLOEXEC);
-       if (tp_fd < 0) {
-               bpf_probe_unregister(raw_tp->btp, prog);
-               err = tp_fd;
-               goto out_put_prog;
-       }
-       return tp_fd;
+       if (tp_fd < 0)
+               bpf_probe_unregister(raw_tp->btp, raw_tp->prog);
 
-out_put_prog:
-       bpf_prog_put(prog);
-out_free_tp:
-       kfree(raw_tp);
-out_put_btp:
-       bpf_put_raw_tracepoint(btp);
-       return err;
+       return tp_fd;
 }
 
 static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog,
@@ -2848,7 +2801,7 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, 
uattr, unsigned int, siz
                err = bpf_obj_get_info_by_fd(&attr, uattr);
                break;
        case BPF_RAW_TRACEPOINT_OPEN:
-               err = bpf_raw_tracepoint_open(&attr);
+               err = bpf_raw_tracepoint_open_syscall(&attr);
                break;
        case BPF_BTF_LOAD:
                err = bpf_btf_load(&attr);
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 1c9a4745e596..c4b543bc617f 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -7,6 +7,7 @@
 #include <linux/slab.h>
 #include <linux/bpf.h>
 #include <linux/bpf_perf_event.h>
+#include <linux/bpf_trace.h>
 #include <linux/filter.h>
 #include <linux/uaccess.h>
 #include <linux/ctype.h>
@@ -1413,3 +1414,58 @@ static int __init bpf_event_init(void)
 
 fs_initcall(bpf_event_init);
 #endif /* CONFIG_MODULES */
+
+void bpf_raw_tracepoint_close(struct bpf_raw_tracepoint *raw_tp)
+{
+       if (raw_tp->prog) {
+               bpf_probe_unregister(raw_tp->btp, raw_tp->prog);
+               bpf_prog_put(raw_tp->prog);
+       }
+       bpf_put_raw_tracepoint(raw_tp->btp);
+       kfree(raw_tp);
+}
+
+struct bpf_raw_tracepoint *bpf_raw_tracepoint_open(char *tp_name, int prog_fd)
+{
+       struct bpf_raw_tracepoint *raw_tp;
+       struct bpf_raw_event_map *btp;
+       struct bpf_prog *prog;
+       int err;
+
+       btp = bpf_get_raw_tracepoint(tp_name);
+       if (!btp)
+               return ERR_PTR(-ENOENT);
+
+       raw_tp = kzalloc(sizeof(*raw_tp), GFP_USER);
+       if (!raw_tp) {
+               err = -ENOMEM;
+               goto out_put_btp;
+       }
+       raw_tp->btp = btp;
+
+       prog = bpf_prog_get(prog_fd);
+       if (IS_ERR(prog)) {
+               err = PTR_ERR(prog);
+               goto out_free_tp;
+       }
+       if (prog->type != BPF_PROG_TYPE_RAW_TRACEPOINT &&
+           prog->type != BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE) {
+               err = -EINVAL;
+               goto out_put_prog;
+       }
+
+       err = bpf_probe_register(raw_tp->btp, prog);
+       if (err)
+               goto out_put_prog;
+
+       raw_tp->prog = prog;
+       return raw_tp;
+
+out_put_prog:
+       bpf_prog_put(prog);
+out_free_tp:
+       kfree(raw_tp);
+out_put_btp:
+       bpf_put_raw_tracepoint(btp);
+       return ERR_PTR(err);
+}
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 0ce3db67f556..67851fb66b6b 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -2017,6 +2017,9 @@ event_create_dir(struct dentry *parent, struct 
trace_event_file *file)
 
                trace_create_file("trigger", 0644, file->dir, file,
                                  &event_trigger_fops);
+
+               trace_create_file("bpf_attach", 0644, file->dir, file,
+                                 &bpf_attach_trigger_fops);
        }
 
 #ifdef CONFIG_HIST_TRIGGERS
-- 
2.22.0.410.gd8fdbe21b5-goog

Reply via email to