Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx> --- kernel/events/core.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -5762,6 +5762,11 @@ static inline struct fd perf_fdget(int f return f; } +static inline bool is_perf_fd(struct fd fd) +{ + return fd.file && fd.file->f_op == &perf_fops; +} + static int perf_event_set_output(struct perf_event *event, struct perf_event *output_event); static int perf_event_set_filter(struct perf_event *event, void __user *arg); @@ -5807,19 +5812,15 @@ static long _perf_ioctl(struct perf_even case PERF_EVENT_IOC_SET_OUTPUT: { - int ret; if (arg != -1) { struct perf_event *output_event; - struct fd output = perf_fdget(arg); - if (!output.file) + CLASS(fd, output)(arg); + if (!is_perf_fd(output)) return -EBADF; output_event = output.file->private_data; - ret = perf_event_set_output(event, output_event); - fdput(output); - } else { - ret = perf_event_set_output(event, NULL); + return perf_event_set_output(event, output_event); } - return ret; + return perf_event_set_output(event, NULL); } case PERF_EVENT_IOC_SET_FILTER: