From patchwork Wed Jan 6 14:55:00 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "George G. Davis" X-Patchwork-Id: 7968531 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id A52589F1C0 for ; Wed, 6 Jan 2016 14:57:30 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9BA692012E for ; Wed, 6 Jan 2016 14:57:29 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3912D200FE for ; Wed, 6 Jan 2016 14:57:28 +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 1aGpUo-0006pQ-4s; Wed, 06 Jan 2016 14:55:30 +0000 Received: from mail-qg0-x235.google.com ([2607:f8b0:400d:c04::235]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1aGpUj-0005hv-IQ for linux-arm-kernel@lists.infradead.org; Wed, 06 Jan 2016 14:55:28 +0000 Received: by mail-qg0-x235.google.com with SMTP id 6so225552853qgy.1 for ; Wed, 06 Jan 2016 06:55:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:to:cc:subject:message-id:references:mime-version :content-type:content-disposition:in-reply-to:user-agent; bh=dOUyp+o2kYiqCLOsmCUkAOafRskGZHRB4nw7bv+EYAA=; b=sHiNEj8A2mU9qkdPkV9cCPgfzuLR+2d9tLX7HELEYBbIJLKlcqGR8MreRKna9Ovyn6 oEOWIyZuMHdJE4el1JI3Eh0BrDpEGPefa89w75ySlOh5czTJUpJimm3rUcYTvv/V9FYp iaXZASN6yrkZ1xUYoJooq9lAVPatRqQZL4f6bSRnzxz2O8LyWeQo3AgBqyj04MNhDzfo DxTDpY4xlTTydFTfeatz2sW9ZSIs+2kkR3mFCXx4PDNSvn0OKU4ECE9KvQ+kneI2CV6Y bvh+fCA5PkesptWlfK4kra7KjFAmmo8/T7I/p8ISiVt34QTIpge79GchWFUJL72UEgTJ Q8nw== X-Received: by 10.140.250.70 with SMTP id v67mr139335873qhc.43.1452092103678; Wed, 06 Jan 2016 06:55:03 -0800 (PST) Received: from gandalf.middle.earth.net (pool-72-74-130-119.bstnma.fios.verizon.net. [72.74.130.119]) by smtp.gmail.com with ESMTPSA id c34sm20919264qgc.14.2016.01.06.06.55.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 06 Jan 2016 06:55:02 -0800 (PST) Date: Wed, 6 Jan 2016 09:55:00 -0500 From: "George G. Davis" To: "linux-arm-kernel@lists.infradead.org" Subject: Re: [PATCH V3 1/1] ARM: perf: Set suniden bit Message-ID: <20160106145500.GA92797@gandalf.middle.earth.net> References: <20140805144831.25462.18149.stgit@localhost> <20140805144833.25462.46011.stgit@localhost> <20140806104947.GD25953@arm.com> <53E22E0B.7080907@parkeon.com> <20140807173316.GH31101@arm.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20140807173316.GH31101@arm.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160106_065527_482564_2306B859 X-CRM114-Status: GOOD ( 18.53 ) X-Spam-Score: -2.7 (--) 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: Martin Fuzzey , "George G. Davis" , Pooya Keshavarzi , Shawn Guao , Will Deacon Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham 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 From: Martin Fuzzey Counters other than the CPU cycle counter only work if the security module SUNIDEN bit is set. Since access to this register is only possible in secure mode it will only be done if the device tree property "secure-reg-access" is set. Without this: # perf stat -e cycles,instructions sleep 1 Performance counter stats for 'sleep 1': 14606094 cycles # 0.000 GHz 0 instructions # 0.00 insns per cycle After applying: # perf stat -e cycles,instructions sleep 1 Performance counter stats for 'sleep 1': 5843809 cycles 2566484 instructions # 0.44 insns per cycle 1.020144000 seconds time elapsed Some platforms (eg i.MX53) may also need additional platform specific setup. Signed-off-by: Martin Fuzzey Signed-off-by: Pooya Keshavarzi Signed-off-by: George G. Davis --- Changes in v3: - Pooya Keshavarzi: * v2 review comment fixups * Use on_each_cpu() to set SUNIDEN on all CPUs * Move armv7pmu_enable_secure_access() call from armv7pmu_start() to armv7_a8_map_event() such that is called only once instead of each time `perf` is executed - George G. Davis: * Fixup to apply after file renames due to commit fa8ad78 (arm: perf: factor arm_pmu core out to drivers) * Fix checkpatch 'CHECK: Prefer using the BIT macro' issue Documentation/devicetree/bindings/arm/pmu.txt | 8 ++++++++ arch/arm/kernel/perf_event_v7.c | 17 +++++++++++++++++ drivers/perf/arm_pmu.c | 3 +++ include/linux/perf/arm_pmu.h | 1 + 4 files changed, 29 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/pmu.txt b/Documentation/devicetree/bindings/arm/pmu.txt index 97ba45a..8d4b831 100644 --- a/Documentation/devicetree/bindings/arm/pmu.txt +++ b/Documentation/devicetree/bindings/arm/pmu.txt @@ -45,6 +45,14 @@ Optional properties: - qcom,no-pc-write : Indicates that this PMU doesn't support the 0xc and 0xd events. +- secure-reg-access : Indicates that secure mode access is available. + This will cause the driver to do any setup required that + is only possible in secure mode. + If not present the secure registers will not be touched, + which means the PMU may fail to operate unless external + code (bootloader or security monitor) has performed the + appropriate initialisation. + Example: pmu { diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c index 126dc67..8dc5582 100644 --- a/arch/arm/kernel/perf_event_v7.c +++ b/arch/arm/kernel/perf_event_v7.c @@ -600,6 +600,11 @@ static const unsigned scorpion_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] #define ARMV7_EXCLUDE_USER (1 << 30) #define ARMV7_INCLUDE_HYP (1 << 27) +/* + * Secure debug enable reg + */ +#define ARMV7_SDER_SUNIDEN BIT(1) /* Permit non-invasive debug */ + static inline u32 armv7_pmnc_read(void) { u32 val; @@ -994,6 +999,15 @@ static void armv7pmu_reset(void *info) armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C); } +static void armv7pmu_enable_secure_access(void *data) +{ + u32 val; + + asm volatile("mrc p15, 0, %0, c1, c1, 1" : "=r" (val)); + val |= ARMV7_SDER_SUNIDEN; + asm volatile("mcr p15, 0, %0, c1, c1, 1" : : "r" (val)); +} + static int armv7_a8_map_event(struct perf_event *event) { return armpmu_map_event(event, &armv7_a8_perf_map, @@ -1060,6 +1074,9 @@ static void armv7pmu_init(struct arm_pmu *cpu_pmu) cpu_pmu->stop = armv7pmu_stop; cpu_pmu->reset = armv7pmu_reset; cpu_pmu->max_period = (1LLU << 32) - 1; + + if (cpu_pmu->secure_access) + on_each_cpu(armv7pmu_enable_secure_access, NULL, 1); }; static void armv7_read_num_pmnc_events(void *info) diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index be3755c..972e6b7 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c @@ -895,6 +895,9 @@ int arm_pmu_device_probe(struct platform_device *pdev, if (node && (of_id = of_match_node(of_table, pdev->dev.of_node))) { init_fn = of_id->data; + pmu->secure_access = of_property_read_bool(pdev->dev.of_node, + "secure-reg-access"); + ret = of_pmu_irq_cfg(pmu); if (!ret) ret = init_fn(pmu); diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h index bfa673b..4b8dc13 100644 --- a/include/linux/perf/arm_pmu.h +++ b/include/linux/perf/arm_pmu.h @@ -104,6 +104,7 @@ struct arm_pmu { atomic_t active_events; struct mutex reserve_mutex; u64 max_period; + bool secure_access; struct platform_device *plat_device; struct pmu_hw_events __percpu *hw_events; struct notifier_block hotplug_nb;