static void *perf_event_fd_array_get_ptr(struct bpf_map *map, int fd) { struct perf_event *event; const struct perf_event_attr *attr; event = perf_event_get(fd); if (IS_ERR(event)) return event; attr = perf_event_attrs(event); if (IS_ERR(attr)) goto err; if (attr->inherit) goto err; if (attr->type == PERF_TYPE_RAW) return event; if (attr->type == PERF_TYPE_HARDWARE) return event; if (attr->type == PERF_TYPE_SOFTWARE && attr->config == PERF_COUNT_SW_BPF_OUTPUT) return event; err: perf_event_release_kernel(event); return ERR_PTR(-EINVAL); }
static void *perf_event_fd_array_get_ptr(struct bpf_map *map, int fd) { struct perf_event *event; const struct perf_event_attr *attr; event = perf_event_get(fd); if (IS_ERR(event)) return event; attr = perf_event_attrs(event); if (IS_ERR(attr)) return (void *)attr; if (attr->type != PERF_TYPE_RAW && attr->type != PERF_TYPE_HARDWARE) { perf_event_release_kernel(event); return ERR_PTR(-EINVAL); } return event; }
static void *perf_event_fd_array_get_ptr(struct bpf_map *map, struct file *map_file, int fd) { const struct perf_event_attr *attr; struct bpf_event_entry *ee; struct perf_event *event; struct file *perf_file; perf_file = perf_event_get(fd); if (IS_ERR(perf_file)) return perf_file; event = perf_file->private_data; ee = ERR_PTR(-EINVAL); attr = perf_event_attrs(event); if (IS_ERR(attr) || attr->inherit) goto err_out; switch (attr->type) { case PERF_TYPE_SOFTWARE: if (attr->config != PERF_COUNT_SW_BPF_OUTPUT) goto err_out; /* fall-through */ case PERF_TYPE_RAW: case PERF_TYPE_HARDWARE: ee = bpf_event_entry_gen(perf_file, map_file); if (ee) return ee; ee = ERR_PTR(-ENOMEM); /* fall-through */ default: break; } err_out: fput(perf_file); return ee; }