The group validation here is erroneously inspecting software events,
as well as other hardware siblings, which are only checked for *after*
they've already been misinterpreted. Once again, just ignore events
which don't belong to our PMU, and don't duplicate what
perf_event_open() will already check for us.

Signed-off-by: Robin Murphy <robin.mur...@arm.com>
---
 drivers/perf/fsl_imx8_ddr_perf.c | 21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c
index b989ffa95d69..56fe281974d2 100644
--- a/drivers/perf/fsl_imx8_ddr_perf.c
+++ b/drivers/perf/fsl_imx8_ddr_perf.c
@@ -331,6 +331,9 @@ static u32 ddr_perf_filter_val(struct perf_event *event)
 static bool ddr_perf_filters_compatible(struct perf_event *a,
                                        struct perf_event *b)
 {
+       /* Ignore grouped events that aren't ours */
+       if (a->pmu != b->pmu)
+               return true;
        if (!ddr_perf_is_filtered(a))
                return true;
        if (!ddr_perf_is_filtered(b))
@@ -409,16 +412,8 @@ static int ddr_perf_event_init(struct perf_event *event)
                return -EOPNOTSUPP;
        }
 
-       /*
-        * We must NOT create groups containing mixed PMUs, although software
-        * events are acceptable (for example to create a CCN group
-        * periodically read when a hrtimer aka cpu-clock leader triggers).
-        */
-       if (event->group_leader->pmu != event->pmu &&
-                       !is_software_event(event->group_leader))
-               return -EINVAL;
-
-       if (pmu->devtype_data->quirks & DDR_CAP_AXI_ID_FILTER) {
+       if (event != event->group_leader &&
+           pmu->devtype_data->quirks & DDR_CAP_AXI_ID_FILTER) {
                if (!ddr_perf_filters_compatible(event, event->group_leader))
                        return -EINVAL;
                for_each_sibling_event(sibling, event->group_leader) {
@@ -427,12 +422,6 @@ static int ddr_perf_event_init(struct perf_event *event)
                }
        }
 
-       for_each_sibling_event(sibling, event->group_leader) {
-               if (sibling->pmu != event->pmu &&
-                               !is_software_event(sibling))
-                       return -EINVAL;
-       }
-
        event->cpu = pmu->cpu;
        hwc->idx = -1;
 
-- 
2.39.2.101.g768bb238c484.dirty


Reply via email to