From: Robin Murphy robin.murphy@arm.com
mainline inclusion from mainline-v5.3-rc1 commit 33e84ea4330da8a16bda8a871d0cd3c872bcd89f category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4A1XO CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
------------------------------------------------------------------------
Ensure that a group will actually fit into the available counters.
Signed-off-by: Robin Murphy robin.murphy@arm.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Qi Liu liuqi115@huawei.com Reviewed-by: Yang Jihong yangjihong1@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/perf/arm_smmuv3_pmu.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c index b60b447dde946..6adbb34ec702f 100644 --- a/drivers/perf/arm_smmuv3_pmu.c +++ b/drivers/perf/arm_smmuv3_pmu.c @@ -324,6 +324,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) @@ -356,18 +357,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;