diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index fbdde119b1ccc75475390030abfc5d6ad6bd2334..78c77a91c3b62a7cec9dd1052c2a2566c92b57df 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -243,6 +243,7 @@ struct perf_event; #define PERF_PMU_CAP_EXCLUSIVE 0x10 #define PERF_PMU_CAP_ITRACE 0x20 #define PERF_PMU_CAP_HETEROGENEOUS_CPUS 0x40 +#define PERF_PMU_CAP_NO_EXCLUDE 0x80 /** * struct pmu - generic performance monitoring unit diff --git a/kernel/events/core.c b/kernel/events/core.c index f6da9e11693dd40deaba3c1208a9b49559109e2f..728186f7b5df601ceaba2f5b156f79c8c06861e7 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -9880,6 +9880,15 @@ static int perf_try_init_event(struct pmu *pmu, struct perf_event *event) if (ctx) perf_event_ctx_unlock(event->group_leader, ctx); + if (!ret) { + if (pmu->capabilities & PERF_PMU_CAP_NO_EXCLUDE && + event_has_any_exclude_flag(event)) { + if (event->destroy) + event->destroy(event); + ret = -EINVAL; + } + } + if (ret) module_put(pmu->module);