From patchwork Tue Aug 9 15:51:07 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Rutland X-Patchwork-Id: 73564 Delivered-To: patch@linaro.org Received: by 10.140.29.52 with SMTP id a49csp553191qga; Tue, 9 Aug 2016 08:52:54 -0700 (PDT) X-Received: by 10.98.86.85 with SMTP id k82mr175084118pfb.82.1470757974244; Tue, 09 Aug 2016 08:52:54 -0700 (PDT) Return-Path: Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id xr3si20185304pab.234.2016.08.09.08.52.54 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Aug 2016 08:52:54 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org designates 2001:1868:205::9 as permitted sender) client-ip=2001:1868:205::9; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org designates 2001:1868:205::9 as permitted sender) smtp.mailfrom=linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bX9Ji-0006ve-Kw; Tue, 09 Aug 2016 15:51:46 +0000 Received: from foss.arm.com ([217.140.101.70]) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bX9Jf-0006tM-1X for linux-arm-kernel@lists.infradead.org; Tue, 09 Aug 2016 15:51:43 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 7AE1B43F; Tue, 9 Aug 2016 08:52:48 -0700 (PDT) Received: from leverpostej.cambridge.arm.com (usa-sjc-imap-foss1.foss.arm.com [10.72.51.249]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 352F33F21A; Tue, 9 Aug 2016 08:51:20 -0700 (PDT) From: Mark Rutland To: linux-arm-kernel@lists.infradead.org Subject: [PATCH] drivers/perf: arm_pmu: fix legacy affinity-less DT support Date: Tue, 9 Aug 2016 16:51:07 +0100 Message-Id: <1470757867-13554-1-git-send-email-mark.rutland@arm.com> X-Mailer: git-send-email 1.9.1 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160809_085143_141414_B1CF5C1E X-CRM114-Status: GOOD ( 15.43 ) X-Spam-Score: -8.3 (--------) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-8.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at http://www.dnswl.org/, high trust [217.140.101.70 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -1.4 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , Marc Zyngier , Catalin Marinas , Will Deacon , geert@linux-m68k.org, robin.murphy@arm.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org Commit 19a469a58720ea96 ("drivers/perf: arm-pmu: Handle per-interrupt affinity mask") relies on using_spi being valid, but this is only initialised correctly in the presence of an interrupt-affinity property, which legacy DTBs do not have. In the absence of an interrupt-affinity property, using_spi is always false (regardless of whether SPIs are actually used), so we call irq_get_percpu_devid_partition(irq). This returns -EINVAL, and we give up, passing on this return value. The code which determines using_spi also verifies that we do not have mixed SPI/PPI interrupts. Even in the absence of an interrupt-affinity property we do not support mixed SPI/PPI cases, so pull the validation logic above the main loop, ensuring that using_spi is always valid. At the same time, have the error message to give the path of the PMU node, rather than a CPU node, as the mismatch is a property of the entire set of PMU interrupts rather than a particular CPU associated with it. Fixes: 19a469a58720ea96 ("drivers/perf: arm-pmu: Handle per-interrupt affinity mask") Signed-off-by: Mark Rutland Reported-by: Geert Uytterhoeven Reported-by: Robin Murphy Tested-by: Robin Murphy Cc: Catalin Marinas Cc: Marc Zyngier Cc: Will Deacon --- drivers/perf/arm_pmu.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) It's been pointed out to me that Marc send a patch a while ago [1] fixing the same issue, but for some reason that didn't get queued. This patch had the added benefit of ensuring we always avoid mismatched SPI/PPI mixes, but otherwise either patch should avoid the issue. Mark. [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2016-July/444404.html -- 1.9.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel Acked-by: Mark Rutland diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index 6ccb994..7d3c690 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c @@ -900,38 +900,41 @@ static int probe_current_pmu(struct arm_pmu *pmu, static int of_pmu_irq_cfg(struct arm_pmu *pmu) { - int *irqs, i = 0; + int *irqs, i; bool using_spi = false; struct platform_device *pdev = pmu->plat_device; + /* Check the IRQ type and prohibit a mix of PPIs and SPIs */ + for (i = 0; i < pdev->num_resources; i++) { + int irq = platform_get_irq(pdev, i); + if (irq >= 0) { + bool spi = !irq_is_percpu(irq); + + if (i > 0 && spi != using_spi) { + pr_err("PPI/SPI IRQ type mismatch for %s!\n", + of_node_full_name(pdev->dev.of_node)); + return -EINVAL; + } + + using_spi = spi; + } + } + irqs = kcalloc(pdev->num_resources, sizeof(*irqs), GFP_KERNEL); if (!irqs) return -ENOMEM; + i = 0; + do { struct device_node *dn; - int cpu, irq; + int cpu; /* See if we have an affinity entry */ dn = of_parse_phandle(pdev->dev.of_node, "interrupt-affinity", i); if (!dn) break; - /* Check the IRQ type and prohibit a mix of PPIs and SPIs */ - irq = platform_get_irq(pdev, i); - if (irq >= 0) { - bool spi = !irq_is_percpu(irq); - - if (i > 0 && spi != using_spi) { - pr_err("PPI/SPI IRQ type mismatch for %s!\n", - dn->name); - kfree(irqs); - return -EINVAL; - } - - using_spi = spi; - } - /* Now look up the logical CPU number */ for_each_possible_cpu(cpu) { struct device_node *cpu_dn;