diff mbox series

[v2,1/2] perf/smmuv3: Validate group size

Message ID 85f2db579f90f0a89d6c6bb4e53191e9ad172805.1564672242.git.robin.murphy@arm.com (mailing list archive)
State Mainlined
Commit 33e84ea4330da8a16bda8a871d0cd3c872bcd89f
Headers show
Series [v2,1/2] perf/smmuv3: Validate group size | expand

Commit Message

Robin Murphy Aug. 1, 2019, 3:22 p.m. UTC
Ensure that a group will actually fit into the available counters.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
v2:
 - fix condition that thought we were only counting siblings
 - don't inadvertently count software events
 - and don't forget the group leader isn't a sibling, grr...

 drivers/perf/arm_smmuv3_pmu.c | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)
diff mbox series

Patch

diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
index da71c741cb46..c65c197b52a7 100644
--- a/drivers/perf/arm_smmuv3_pmu.c
+++ b/drivers/perf/arm_smmuv3_pmu.c
@@ -323,6 +323,7 @@  static int smmu_pmu_event_init(struct perf_event *event)
 	struct smmu_pmu *smmu_pmu = to_smmu_pmu(event->pmu);
 	struct device *dev = smmu_pmu->dev;
 	struct perf_event *sibling;
+	int group_num_events = 1;
 	u16 event_id;
 
 	if (event->attr.type != event->pmu->type)
@@ -347,18 +348,23 @@  static int smmu_pmu_event_init(struct perf_event *event)
 	}
 
 	/* Don't allow groups with mixed PMUs, except for s/w events */
-	if (event->group_leader->pmu != event->pmu &&
-	    !is_software_event(event->group_leader)) {
-		dev_dbg(dev, "Can't create mixed PMU group\n");
-		return -EINVAL;
+	if (!is_software_event(event->group_leader)) {
+		if (event->group_leader->pmu != event->pmu)
+			return -EINVAL;
+
+		if (++group_num_events > smmu_pmu->num_counters)
+			return -EINVAL;
 	}
 
 	for_each_sibling_event(sibling, event->group_leader) {
-		if (sibling->pmu != event->pmu &&
-		    !is_software_event(sibling)) {
-			dev_dbg(dev, "Can't create mixed PMU group\n");
+		if (is_software_event(sibling))
+			continue;
+
+		if (sibling->pmu != event->pmu)
+			return -EINVAL;
+
+		if (++group_num_events > smmu_pmu->num_counters)
 			return -EINVAL;
-		}
 	}
 
 	hwc->idx = -1;