From patchwork Fri Nov 7 16:25:30 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Rutland X-Patchwork-Id: 5254241 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 411F2C11AC for ; Fri, 7 Nov 2014 16:29:41 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4066420145 for ; Fri, 7 Nov 2014 16:29:40 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4FF3A20117 for ; Fri, 7 Nov 2014 16:29:39 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1XmmNd-00086a-Si; Fri, 07 Nov 2014 16:27:21 +0000 Received: from cam-admin0.cambridge.arm.com ([217.140.96.50]) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1XmmNJ-0007ns-3y for linux-arm-kernel@lists.infradead.org; Fri, 07 Nov 2014 16:27:02 +0000 Received: from leverpostej.cambridge.arm.com (leverpostej.cambridge.arm.com [10.1.205.151]) by cam-admin0.cambridge.arm.com (8.12.6/8.12.6) with ESMTP id sA7GPwwt014702; Fri, 7 Nov 2014 16:26:42 GMT From: Mark Rutland To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 05/11] arm: perf: reject multi-pmu groups Date: Fri, 7 Nov 2014 16:25:30 +0000 Message-Id: <1415377536-12841-6-git-send-email-mark.rutland@arm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1415377536-12841-1-git-send-email-mark.rutland@arm.com> References: <1415377536-12841-1-git-send-email-mark.rutland@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20141107_082701_534323_4AB60EF8 X-CRM114-Status: GOOD ( 14.16 ) X-Spam-Score: -5.6 (-----) Cc: Mark Rutland , will.deacon@arm.com, linux-kernel@vger.kernel.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP An event group spanning multiple CPU PMUs can never be scheduled, as at least one event should always fail, and are therefore nonsensical. Additionally, groups spanning multiple PMUs would require additional validation logic throughout the driver to prevent CPU PMUs from stepping on each others' internal state. Given that such groups are nonsensical to begin with, the simple option is to reject such groups entirely. Groups consisting of software events and CPU PMU events are benign so long as the CPU PMU events only target a single CPU PMU. This patch ensures that we reject the creation of event groups which span multiple CPU PMUs, avoiding the issues described above. The addition of this_pmu to the validation logic made the fake_pmu more confusing than it already was; so this is renamed to the more accurate hw_events. As hw_events was being modified anyway, the initialisation of hw_events.used_mask is also simplified with the use of a designated initializer rather than the existing memset. Signed-off-by: Mark Rutland --- arch/arm/kernel/perf_event.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index b00f6aa..41dcfc0 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -258,13 +258,17 @@ out: } static int -validate_event(struct pmu_hw_events *hw_events, +validate_event(struct pmu *this_pmu, + struct pmu_hw_events *hw_events, struct perf_event *event) { struct arm_pmu *armpmu = to_arm_pmu(event->pmu); if (is_software_event(event)) return 1; + + if (event->pmu != this_pmu) + return 0; if (event->state < PERF_EVENT_STATE_OFF) return 1; @@ -279,23 +283,20 @@ static int validate_group(struct perf_event *event) { struct perf_event *sibling, *leader = event->group_leader; - struct pmu_hw_events fake_pmu; - - /* - * Initialise the fake PMU. We only need to populate the - * used_mask for the purposes of validation. - */ - memset(&fake_pmu.used_mask, 0, sizeof(fake_pmu.used_mask)); + struct pmu *this_pmu = event->pmu; + struct pmu_hw_events hw_events = { + .used_mask = { 0 }, + }; - if (!validate_event(&fake_pmu, leader)) + if (!validate_event(this_pmu, &hw_events, leader)) return -EINVAL; list_for_each_entry(sibling, &leader->sibling_list, group_entry) { - if (!validate_event(&fake_pmu, sibling)) + if (!validate_event(this_pmu, &hw_events, sibling)) return -EINVAL; } - if (!validate_event(&fake_pmu, event)) + if (!validate_event(this_pmu, &hw_events, event)) return -EINVAL; return 0;