Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
0002 /* Copyright (c) 2020 Facebook */
0003 #include <vmlinux.h>
0004 #include <bpf/bpf_helpers.h>
0005 #include <bpf/bpf_core_read.h>
0006 #include <bpf/bpf_tracing.h>
0007 #include "pid_iter.h"
0008 
0009 /* keep in sync with the definition in main.h */
0010 enum bpf_obj_type {
0011     BPF_OBJ_UNKNOWN,
0012     BPF_OBJ_PROG,
0013     BPF_OBJ_MAP,
0014     BPF_OBJ_LINK,
0015     BPF_OBJ_BTF,
0016 };
0017 
0018 extern const void bpf_link_fops __ksym;
0019 extern const void bpf_map_fops __ksym;
0020 extern const void bpf_prog_fops __ksym;
0021 extern const void btf_fops __ksym;
0022 
0023 const volatile enum bpf_obj_type obj_type = BPF_OBJ_UNKNOWN;
0024 
0025 static __always_inline __u32 get_obj_id(void *ent, enum bpf_obj_type type)
0026 {
0027     switch (type) {
0028     case BPF_OBJ_PROG:
0029         return BPF_CORE_READ((struct bpf_prog *)ent, aux, id);
0030     case BPF_OBJ_MAP:
0031         return BPF_CORE_READ((struct bpf_map *)ent, id);
0032     case BPF_OBJ_BTF:
0033         return BPF_CORE_READ((struct btf *)ent, id);
0034     case BPF_OBJ_LINK:
0035         return BPF_CORE_READ((struct bpf_link *)ent, id);
0036     default:
0037         return 0;
0038     }
0039 }
0040 
0041 /* could be used only with BPF_LINK_TYPE_PERF_EVENT links */
0042 static __u64 get_bpf_cookie(struct bpf_link *link)
0043 {
0044     struct bpf_perf_link *perf_link;
0045     struct perf_event *event;
0046 
0047     perf_link = container_of(link, struct bpf_perf_link, link);
0048     event = BPF_CORE_READ(perf_link, perf_file, private_data);
0049     return BPF_CORE_READ(event, bpf_cookie);
0050 }
0051 
0052 SEC("iter/task_file")
0053 int iter(struct bpf_iter__task_file *ctx)
0054 {
0055     struct file *file = ctx->file;
0056     struct task_struct *task = ctx->task;
0057     struct pid_iter_entry e;
0058     const void *fops;
0059 
0060     if (!file || !task)
0061         return 0;
0062 
0063     switch (obj_type) {
0064     case BPF_OBJ_PROG:
0065         fops = &bpf_prog_fops;
0066         break;
0067     case BPF_OBJ_MAP:
0068         fops = &bpf_map_fops;
0069         break;
0070     case BPF_OBJ_BTF:
0071         fops = &btf_fops;
0072         break;
0073     case BPF_OBJ_LINK:
0074         fops = &bpf_link_fops;
0075         break;
0076     default:
0077         return 0;
0078     }
0079 
0080     if (file->f_op != fops)
0081         return 0;
0082 
0083     __builtin_memset(&e, 0, sizeof(e));
0084     e.pid = task->tgid;
0085     e.id = get_obj_id(file->private_data, obj_type);
0086 
0087     if (obj_type == BPF_OBJ_LINK) {
0088         struct bpf_link *link = (struct bpf_link *) file->private_data;
0089 
0090         if (BPF_CORE_READ(link, type) == BPF_LINK_TYPE_PERF_EVENT) {
0091             e.has_bpf_cookie = true;
0092             e.bpf_cookie = get_bpf_cookie(link);
0093         }
0094     }
0095 
0096     bpf_probe_read_kernel_str(&e.comm, sizeof(e.comm),
0097                   task->group_leader->comm);
0098     bpf_seq_write(ctx->meta->seq, &e, sizeof(e));
0099 
0100     return 0;
0101 }
0102 
0103 char LICENSE[] SEC("license") = "Dual BSD/GPL";