diff options
-rw-r--r-- | kernel/events/core.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index f2b865c0e182..65e20c5c3c44 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -12503,15 +12503,21 @@ SYSCALL_DEFINE5(perf_event_open, * perf_event_pmu_context. */ pmu = group_leader->pmu_ctx->pmu; - } else if (!is_software_event(event) && - is_software_event(group_leader) && - (group_leader->group_caps & PERF_EV_CAP_SOFTWARE)) { - /* - * In case the group is a pure software group, and we - * try to add a hardware event, move the whole group to - * the hardware context. - */ - move_group = 1; + } else if (!is_software_event(event)) { + if (is_software_event(group_leader) && + (group_leader->group_caps & PERF_EV_CAP_SOFTWARE)) { + /* + * In case the group is a pure software group, and we + * try to add a hardware event, move the whole group to + * the hardware context. + */ + move_group = 1; + } + + /* Don't allow group of multiple hw events from different pmus */ + if (!in_software_context(group_leader) && + group_leader->pmu_ctx->pmu != pmu) + goto err_locked; } } |