bpf: Add tracing_multi link info support

Adding BPF_OBJ_GET_INFO_BY_FD support for tracing_multi links.

We expose following tracing_multi link data:
- attach_type of the program
- number of ids
- array of BTF ids
- array of its related kernel addresses
- array of cookies

The change follows the kprobe_multi and uprobe_multi link-info convention
of optional output arrays with an in/out count,

On top of standard tracing link data we also expose addresses, because they
are useful info for user (especially when the attachment was done via pattern).
This data is hidden when kallsyms does not allow exposing kernel pointer values.

Assisted-by: Codex:GPT-5

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Leon Hwang <leon.hwang@linux.dev>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20260629212208.895962-2-jolsa@kernel.org
This commit is contained in:
Jiri Olsa 2026-06-29 23:22:06 +02:00 committed by Andrii Nakryiko
parent 09e7d46e33
commit 859055e076
3 changed files with 73 additions and 0 deletions

View File

@ -6842,6 +6842,15 @@ struct bpf_link_info {
__u32 flags;
__u32 pid;
} uprobe_multi;
struct {
__u32 attach_type;
__u32 count; /* in/out: tracing_multi target count */
__u32 btf_obj_id;
__u32 :32;
__aligned_u64 ids;
__aligned_u64 addrs;
__aligned_u64 cookies;
} tracing_multi;
struct {
__u32 type; /* enum bpf_perf_event_type */
__u32 :32;

View File

@ -3700,6 +3700,60 @@ static void bpf_tracing_multi_link_dealloc(struct bpf_link *link)
kvfree(tr_link);
}
static int bpf_tracing_multi_link_fill_link_info(const struct bpf_link *link,
struct bpf_link_info *info)
{
u64 __user *ucookies = u64_to_user_ptr(info->tracing_multi.cookies);
u64 __user *uaddrs = u64_to_user_ptr(info->tracing_multi.addrs);
u32 __user *uids = u64_to_user_ptr(info->tracing_multi.ids);
struct bpf_tracing_multi_link *tr_link;
u32 ucount = info->tracing_multi.count;
bool has_cookies, show_addrs;
int err = 0;
if ((uids || ucookies || uaddrs) && !ucount)
return -EINVAL;
tr_link = container_of(link, struct bpf_tracing_multi_link, link);
info->tracing_multi.attach_type = tr_link->link.attach_type;
info->tracing_multi.count = tr_link->nodes_cnt;
info->tracing_multi.btf_obj_id = btf_obj_id(tr_link->link.prog->aux->attach_btf);
if (!uids && !ucookies && !uaddrs)
return 0;
if (ucount < tr_link->nodes_cnt)
err = -ENOSPC;
else
ucount = tr_link->nodes_cnt;
has_cookies = !!tr_link->cookies;
show_addrs = kallsyms_show_value(current_cred());
for (int i = 0; i < ucount; i++) {
struct bpf_tracing_multi_node *mnode = &tr_link->nodes[i];
u64 addr, cookie;
u32 id;
bpf_trampoline_unpack_key(mnode->trampoline->key, NULL, &id);
addr = show_addrs ? mnode->trampoline->ip : 0;
cookie = has_cookies ? tr_link->cookies[i] : 0;
if (uids && put_user(id, uids + i))
return -EFAULT;
if (uaddrs && put_user(addr, uaddrs + i))
return -EFAULT;
if (ucookies && put_user(cookie, ucookies + i))
return -EFAULT;
cond_resched();
}
return err;
}
#ifdef CONFIG_PROC_FS
static void bpf_tracing_multi_show_fdinfo(const struct bpf_link *link,
struct seq_file *seq)
@ -3730,6 +3784,7 @@ static void bpf_tracing_multi_show_fdinfo(const struct bpf_link *link,
static const struct bpf_link_ops bpf_tracing_multi_link_lops = {
.release = bpf_tracing_multi_link_release,
.dealloc_deferred = bpf_tracing_multi_link_dealloc,
.fill_link_info = bpf_tracing_multi_link_fill_link_info,
#ifdef CONFIG_PROC_FS
.show_fdinfo = bpf_tracing_multi_show_fdinfo,
#endif

View File

@ -6842,6 +6842,15 @@ struct bpf_link_info {
__u32 flags;
__u32 pid;
} uprobe_multi;
struct {
__u32 attach_type;
__u32 count; /* in/out: tracing_multi target count */
__u32 btf_obj_id;
__u32 :32;
__aligned_u64 ids;
__aligned_u64 addrs;
__aligned_u64 cookies;
} tracing_multi;
struct {
__u32 type; /* enum bpf_perf_event_type */
__u32 :32;