Adding support to attach unique generic uprobe by adding the 'unique'
bool flag to struct bpf_uprobe_opts.

Signed-off-by: Jiri Olsa <jo...@kernel.org>
---
 tools/lib/bpf/libbpf.c | 29 ++++++++++++++++++++++++-----
 tools/lib/bpf/libbpf.h |  4 +++-
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 1f613a5f95b6..aac2bd4fb95e 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -11045,11 +11045,19 @@ static int determine_uprobe_retprobe_bit(void)
        return parse_uint_from_file(file, "config:%d\n");
 }
 
+static int determine_uprobe_unique_bit(void)
+{
+       const char *file = "/sys/bus/event_source/devices/uprobe/format/unique";
+
+       return parse_uint_from_file(file, "config:%d\n");
+}
+
 #define PERF_UPROBE_REF_CTR_OFFSET_BITS 32
 #define PERF_UPROBE_REF_CTR_OFFSET_SHIFT 32
 
 static int perf_event_open_probe(bool uprobe, bool retprobe, const char *name,
-                                uint64_t offset, int pid, size_t ref_ctr_off)
+                                uint64_t offset, int pid, size_t ref_ctr_off,
+                                bool unique)
 {
        const size_t attr_sz = sizeof(struct perf_event_attr);
        struct perf_event_attr attr;
@@ -11080,6 +11088,16 @@ static int perf_event_open_probe(bool uprobe, bool 
retprobe, const char *name,
                }
                attr.config |= 1 << bit;
        }
+       if (uprobe && unique) {
+               int bit = determine_uprobe_unique_bit();
+
+               if (bit < 0) {
+                       pr_warn("failed to determine uprobe unique bit: %s\n",
+                               errstr(bit));
+                       return bit;
+               }
+               attr.config |= 1 << bit;
+       }
        attr.size = attr_sz;
        attr.type = type;
        attr.config |= (__u64)ref_ctr_off << PERF_UPROBE_REF_CTR_OFFSET_SHIFT;
@@ -11286,7 +11304,7 @@ int probe_kern_syscall_wrapper(int token_fd)
        if (determine_kprobe_perf_type() >= 0) {
                int pfd;
 
-               pfd = perf_event_open_probe(false, false, syscall_name, 0, 
getpid(), 0);
+               pfd = perf_event_open_probe(false, false, syscall_name, 0, 
getpid(), 0, false);
                if (pfd >= 0)
                        close(pfd);
 
@@ -11348,7 +11366,7 @@ bpf_program__attach_kprobe_opts(const struct 
bpf_program *prog,
        if (!legacy) {
                pfd = perf_event_open_probe(false /* uprobe */, retprobe,
                                            func_name, offset,
-                                           -1 /* pid */, 0 /* ref_ctr_off */);
+                                           -1 /* pid */, 0 /* ref_ctr_off */, 
false /* unique */);
        } else {
                char probe_name[MAX_EVENT_NAME_LEN];
 
@@ -12251,7 +12269,7 @@ bpf_program__attach_uprobe_opts(const struct 
bpf_program *prog, pid_t pid,
        struct bpf_link *link;
        size_t ref_ctr_off;
        int pfd, err;
-       bool retprobe, legacy;
+       bool retprobe, legacy, unique;
        const char *func_name;
 
        if (!OPTS_VALID(opts, bpf_uprobe_opts))
@@ -12261,6 +12279,7 @@ bpf_program__attach_uprobe_opts(const struct 
bpf_program *prog, pid_t pid,
        retprobe = OPTS_GET(opts, retprobe, false);
        ref_ctr_off = OPTS_GET(opts, ref_ctr_offset, 0);
        pe_opts.bpf_cookie = OPTS_GET(opts, bpf_cookie, 0);
+       unique = OPTS_GET(opts, unique, false);
 
        if (!binary_path)
                return libbpf_err_ptr(-EINVAL);
@@ -12321,7 +12340,7 @@ bpf_program__attach_uprobe_opts(const struct 
bpf_program *prog, pid_t pid,
 
        if (!legacy) {
                pfd = perf_event_open_probe(true /* uprobe */, retprobe, 
binary_path,
-                                           func_offset, pid, ref_ctr_off);
+                                           func_offset, pid, ref_ctr_off, 
unique);
        } else {
                char probe_name[MAX_EVENT_NAME_LEN];
 
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 13a10299331b..0a38dee1d9c1 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -701,9 +701,11 @@ struct bpf_uprobe_opts {
        const char *func_name;
        /* uprobe attach mode */
        enum probe_attach_mode attach_mode;
+       /* create unique uprobe */
+       bool unique;
        size_t :0;
 };
-#define bpf_uprobe_opts__last_field attach_mode
+#define bpf_uprobe_opts__last_field unique
 
 /**
  * @brief **bpf_program__attach_uprobe()** attaches a BPF program
-- 
2.51.0


Reply via email to