Adding support to attach program in uprobe session mode
with bpf_program__attach_uprobe_multi function.

Adding session bool to bpf_uprobe_multi_opts struct that allows
to load and attach the bpf program via uprobe session.
the attachment to create uprobe multi session.

Also adding new program loader section that allows:
  SEC("uprobe.session/bpf_fentry_test*")

and loads/attaches uprobe program as uprobe session.

Adding sleepable hook (uprobe.session.s) as well.

Signed-off-by: Jiri Olsa <jo...@kernel.org>
---
 tools/lib/bpf/bpf.c    |  1 +
 tools/lib/bpf/libbpf.c | 21 ++++++++++++++++++---
 tools/lib/bpf/libbpf.h |  4 +++-
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 2a4c71501a17..becdfa701c75 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -776,6 +776,7 @@ int bpf_link_create(int prog_fd, int target_fd,
                        return libbpf_err(-EINVAL);
                break;
        case BPF_TRACE_UPROBE_MULTI:
+       case BPF_TRACE_UPROBE_SESSION:
                attr.link_create.uprobe_multi.flags = OPTS_GET(opts, 
uprobe_multi.flags, 0);
                attr.link_create.uprobe_multi.cnt = OPTS_GET(opts, 
uprobe_multi.cnt, 0);
                attr.link_create.uprobe_multi.path = ptr_to_u64(OPTS_GET(opts, 
uprobe_multi.path, 0));
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 6917d4a0bd4e..83e56856b2b4 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -9363,8 +9363,10 @@ static const struct bpf_sec_def section_defs[] = {
        SEC_DEF("kprobe.session+",      KPROBE, BPF_TRACE_KPROBE_SESSION, 
SEC_NONE, attach_kprobe_session),
        SEC_DEF("uprobe.multi+",        KPROBE, BPF_TRACE_UPROBE_MULTI, 
SEC_NONE, attach_uprobe_multi),
        SEC_DEF("uretprobe.multi+",     KPROBE, BPF_TRACE_UPROBE_MULTI, 
SEC_NONE, attach_uprobe_multi),
+       SEC_DEF("uprobe.session+",      KPROBE, BPF_TRACE_UPROBE_SESSION, 
SEC_NONE, attach_uprobe_multi),
        SEC_DEF("uprobe.multi.s+",      KPROBE, BPF_TRACE_UPROBE_MULTI, 
SEC_SLEEPABLE, attach_uprobe_multi),
        SEC_DEF("uretprobe.multi.s+",   KPROBE, BPF_TRACE_UPROBE_MULTI, 
SEC_SLEEPABLE, attach_uprobe_multi),
+       SEC_DEF("uprobe.session.s+",    KPROBE, BPF_TRACE_UPROBE_SESSION, 
SEC_SLEEPABLE, attach_uprobe_multi),
        SEC_DEF("ksyscall+",            KPROBE, 0, SEC_NONE, attach_ksyscall),
        SEC_DEF("kretsyscall+",         KPROBE, 0, SEC_NONE, attach_ksyscall),
        SEC_DEF("usdt+",                KPROBE, 0, SEC_USDT, attach_usdt),
@@ -11684,7 +11686,10 @@ static int attach_uprobe_multi(const struct 
bpf_program *prog, long cookie, stru
                ret = 0;
                break;
        case 3:
-               opts.retprobe = str_has_pfx(probe_type, "uretprobe.multi");
+               if (str_has_pfx(probe_type, "uprobe.session"))
+                       opts.session = true;
+               else
+                       opts.retprobe = str_has_pfx(probe_type, 
"uretprobe.multi");
                *link = bpf_program__attach_uprobe_multi(prog, -1, binary_path, 
func_name, &opts);
                ret = libbpf_get_error(*link);
                break;
@@ -11933,10 +11938,12 @@ bpf_program__attach_uprobe_multi(const struct 
bpf_program *prog,
        const unsigned long *ref_ctr_offsets = NULL, *offsets = NULL;
        LIBBPF_OPTS(bpf_link_create_opts, lopts);
        unsigned long *resolved_offsets = NULL;
+       enum bpf_attach_type attach_type;
        int err = 0, link_fd, prog_fd;
        struct bpf_link *link = NULL;
        char errmsg[STRERR_BUFSIZE];
        char full_path[PATH_MAX];
+       bool retprobe, session;
        const __u64 *cookies;
        const char **syms;
        size_t cnt;
@@ -12007,12 +12014,20 @@ bpf_program__attach_uprobe_multi(const struct 
bpf_program *prog,
                offsets = resolved_offsets;
        }
 
+       retprobe = OPTS_GET(opts, retprobe, false);
+       session  = OPTS_GET(opts, session, false);
+
+       if (retprobe && session)
+               return libbpf_err_ptr(-EINVAL);
+
+       attach_type = session ? BPF_TRACE_UPROBE_SESSION : 
BPF_TRACE_UPROBE_MULTI;
+
        lopts.uprobe_multi.path = path;
        lopts.uprobe_multi.offsets = offsets;
        lopts.uprobe_multi.ref_ctr_offsets = ref_ctr_offsets;
        lopts.uprobe_multi.cookies = cookies;
        lopts.uprobe_multi.cnt = cnt;
-       lopts.uprobe_multi.flags = OPTS_GET(opts, retprobe, false) ? 
BPF_F_UPROBE_MULTI_RETURN : 0;
+       lopts.uprobe_multi.flags = retprobe ? BPF_F_UPROBE_MULTI_RETURN : 0;
 
        if (pid == 0)
                pid = getpid();
@@ -12026,7 +12041,7 @@ bpf_program__attach_uprobe_multi(const struct 
bpf_program *prog,
        }
        link->detach = &bpf_link__detach_fd;
 
-       link_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_UPROBE_MULTI, &lopts);
+       link_fd = bpf_link_create(prog_fd, 0, attach_type, &lopts);
        if (link_fd < 0) {
                err = -errno;
                pr_warn("prog '%s': failed to attach multi-uprobe: %s\n",
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 64a6a3d323e3..f6a7835dc519 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -569,10 +569,12 @@ struct bpf_uprobe_multi_opts {
        size_t cnt;
        /* create return uprobes */
        bool retprobe;
+       /* create session kprobes */
+       bool session;
        size_t :0;
 };
 
-#define bpf_uprobe_multi_opts__last_field retprobe
+#define bpf_uprobe_multi_opts__last_field session
 
 /**
  * @brief **bpf_program__attach_uprobe_multi()** attaches a BPF program
-- 
2.46.0


Reply via email to