1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2 /* Copyright (c) 2020 Facebook */
4 #include <bpf/bpf_helpers.h>
5 #include <bpf/bpf_core_read.h>
6 #include <bpf/bpf_tracing.h>
9 /* keep in sync with the definition in main.h */
18 struct bpf_perf_link___local
{
20 struct file
*perf_file
;
21 } __attribute__((preserve_access_index
));
23 struct perf_event___local
{
25 } __attribute__((preserve_access_index
));
27 enum bpf_link_type___local
{
28 BPF_LINK_TYPE_PERF_EVENT___local
= 7,
31 extern const void bpf_link_fops __ksym
;
32 extern const void bpf_link_fops_poll __ksym __weak
;
33 extern const void bpf_map_fops __ksym
;
34 extern const void bpf_prog_fops __ksym
;
35 extern const void btf_fops __ksym
;
37 const volatile enum bpf_obj_type obj_type
= BPF_OBJ_UNKNOWN
;
39 static __always_inline __u32
get_obj_id(void *ent
, enum bpf_obj_type type
)
43 return BPF_CORE_READ((struct bpf_prog
*)ent
, aux
, id
);
45 return BPF_CORE_READ((struct bpf_map
*)ent
, id
);
47 return BPF_CORE_READ((struct btf
*)ent
, id
);
49 return BPF_CORE_READ((struct bpf_link
*)ent
, id
);
55 /* could be used only with BPF_LINK_TYPE_PERF_EVENT links */
56 static __u64
get_bpf_cookie(struct bpf_link
*link
)
58 struct bpf_perf_link___local
*perf_link
;
59 struct perf_event___local
*event
;
61 perf_link
= container_of(link
, struct bpf_perf_link___local
, link
);
62 event
= BPF_CORE_READ(perf_link
, perf_file
, private_data
);
63 return BPF_CORE_READ(event
, bpf_cookie
);
67 int iter(struct bpf_iter__task_file
*ctx
)
69 struct file
*file
= ctx
->file
;
70 struct task_struct
*task
= ctx
->task
;
71 struct pid_iter_entry e
;
79 fops
= &bpf_prog_fops
;
88 if (&bpf_link_fops_poll
&&
89 file
->f_op
== &bpf_link_fops_poll
)
90 fops
= &bpf_link_fops_poll
;
92 fops
= &bpf_link_fops
;
98 if (file
->f_op
!= fops
)
101 __builtin_memset(&e
, 0, sizeof(e
));
103 e
.id
= get_obj_id(file
->private_data
, obj_type
);
105 if (obj_type
== BPF_OBJ_LINK
&&
106 bpf_core_enum_value_exists(enum bpf_link_type___local
,
107 BPF_LINK_TYPE_PERF_EVENT___local
)) {
108 struct bpf_link
*link
= (struct bpf_link
*) file
->private_data
;
110 if (BPF_CORE_READ(link
, type
) == bpf_core_enum_value(enum bpf_link_type___local
,
111 BPF_LINK_TYPE_PERF_EVENT___local
)) {
112 e
.has_bpf_cookie
= true;
113 e
.bpf_cookie
= get_bpf_cookie(link
);
117 bpf_probe_read_kernel_str(&e
.comm
, sizeof(e
.comm
),
118 task
->group_leader
->comm
);
119 bpf_seq_write(ctx
->meta
->seq
, &e
, sizeof(e
));
124 char LICENSE
[] SEC("license") = "Dual BSD/GPL";