All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] perf: Enabling PMUv3 on 32bit ARM systems
@ 2017-03-24 12:15 Marc Zyngier
  2017-03-24 12:15 ` [PATCH 1/4] arm64: perf: Move PMUv3 driver to drivers/perf Marc Zyngier
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Marc Zyngier @ 2017-03-24 12:15 UTC (permalink / raw)
  To: linux-arm-kernel

PMUv3 has been introduced with ARMv8 and, while it has only been used
on 64bit systems so far, it would definitely be useful for 32bit
guests running under KVM, for example.

This is done in three steps:
(1) Move the driver from arch/arm64 to drivers/perf
(2) Add a handful of system register accessors so that we can reuse
    the driver on 32bit
(3) Provide the same accessors on 32bit, enable compilation, and
    make it the default selection for mach-virt.

The one thing that I find a bit dodgy is the use of CONFIG_CPU_V7 to
allow the selection of the driver. I'm not sure if we should just
remove it altogether (it should never probe on anything but an ARMv8
CPU), or define a CONFIG_CPU_V8... Guidance appreciated.

Tested on a 32bit VM running on a X-Gene system:

root at zomby-woof:~# uname -a
Linux zomby-woof 4.11.0-rc3+ #6979 SMP PREEMPT Fri Mar 24 10:01:42 GMT 2017 armv7l GNU/Linux
root at zomby-woof:~# dmesg | grep -i pmu
[    2.440279] hw perfevents: enabled with armv8_pmuv3 PMU driver, 5 counters available
root at zomby-woof:~# perf stat -e cycles,L1-icache-loads,dTLB-load-misses ~maz/hackbench 100 process 1000
Running with 100*40 (== 4000) tasks.
Time: 59.370

 Performance counter stats for '/home/maz/hackbench 100 process 1000':

      323663890100      cycles                                                      
       46297944079      L1-icache-loads                                             
           6570884      dTLB-load-misses                                            

      60.777397600 seconds time elapsed

Marc Zyngier (4):
  arm64: perf: Move PMUv3 driver to drivers/perf
  arm64: perf: Abstract system register accesses away
  ARM: perf: Allow the use of the PMUv3 driver on 32bit ARM
  ARM: mach-virt: Select PMUv3 driver by default

 arch/arm/Kconfig                                   |   1 +
 arch/arm/include/asm/arm_pmuv3.h                   | 115 +++++++++++++++++++++
 arch/arm64/include/asm/arm_pmuv3.h                 | 102 ++++++++++++++++++
 arch/arm64/include/asm/perf_event.h                |  55 ----------
 arch/arm64/kernel/Makefile                         |   1 -
 drivers/perf/Kconfig                               |   9 ++
 drivers/perf/Makefile                              |   1 +
 .../perf_event.c => drivers/perf/arm_pmuv3.c       |  36 +++----
 include/kvm/arm_pmu.h                              |   2 +-
 include/linux/perf/arm_pmuv3.h                     |  77 ++++++++++++++
 10 files changed, 324 insertions(+), 75 deletions(-)
 create mode 100644 arch/arm/include/asm/arm_pmuv3.h
 create mode 100644 arch/arm64/include/asm/arm_pmuv3.h
 rename arch/arm64/kernel/perf_event.c => drivers/perf/arm_pmuv3.c (98%)
 create mode 100644 include/linux/perf/arm_pmuv3.h

-- 
2.11.0

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/4] arm64: perf: Move PMUv3 driver to drivers/perf
  2017-03-24 12:15 [PATCH 0/4] perf: Enabling PMUv3 on 32bit ARM systems Marc Zyngier
@ 2017-03-24 12:15 ` Marc Zyngier
  2017-03-24 12:15 ` [PATCH 2/4] arm64: perf: Abstract system register accesses away Marc Zyngier
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Marc Zyngier @ 2017-03-24 12:15 UTC (permalink / raw)
  To: linux-arm-kernel

Having the ARM PMUv3 driver sitting in arch/arm64/kernel is getting
in the way of being able to use perf on ARMv8 cores running a 32bit
kernel, such as 32bit KVM guests.

This patch moves it into drivers/perf/arm_pmuv3.c, with an include
file in include/linux/perf/arm_pmuv3.h. The only thing left in
arch/arm64 is some mundane perf stuff.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/perf_event.h                | 55 ----------------
 arch/arm64/kernel/Makefile                         |  1 -
 drivers/perf/Kconfig                               |  9 +++
 drivers/perf/Makefile                              |  1 +
 .../perf_event.c => drivers/perf/arm_pmuv3.c       |  1 +
 include/kvm/arm_pmu.h                              |  2 +-
 include/linux/perf/arm_pmuv3.h                     | 75 ++++++++++++++++++++++
 7 files changed, 87 insertions(+), 57 deletions(-)
 rename arch/arm64/kernel/perf_event.c => drivers/perf/arm_pmuv3.c (99%)
 create mode 100644 include/linux/perf/arm_pmuv3.h

diff --git a/arch/arm64/include/asm/perf_event.h b/arch/arm64/include/asm/perf_event.h
index 8d5cbec17d80..91b6be092ce2 100644
--- a/arch/arm64/include/asm/perf_event.h
+++ b/arch/arm64/include/asm/perf_event.h
@@ -19,61 +19,6 @@
 
 #include <asm/stack_pointer.h>
 
-#define	ARMV8_PMU_MAX_COUNTERS	32
-#define	ARMV8_PMU_COUNTER_MASK	(ARMV8_PMU_MAX_COUNTERS - 1)
-
-/*
- * Per-CPU PMCR: config reg
- */
-#define ARMV8_PMU_PMCR_E	(1 << 0) /* Enable all counters */
-#define ARMV8_PMU_PMCR_P	(1 << 1) /* Reset all counters */
-#define ARMV8_PMU_PMCR_C	(1 << 2) /* Cycle counter reset */
-#define ARMV8_PMU_PMCR_D	(1 << 3) /* CCNT counts every 64th cpu cycle */
-#define ARMV8_PMU_PMCR_X	(1 << 4) /* Export to ETM */
-#define ARMV8_PMU_PMCR_DP	(1 << 5) /* Disable CCNT if non-invasive debug*/
-#define ARMV8_PMU_PMCR_LC	(1 << 6) /* Overflow on 64 bit cycle counter */
-#define	ARMV8_PMU_PMCR_N_SHIFT	11	 /* Number of counters supported */
-#define	ARMV8_PMU_PMCR_N_MASK	0x1f
-#define	ARMV8_PMU_PMCR_MASK	0x7f	 /* Mask for writable bits */
-
-/*
- * PMOVSR: counters overflow flag status reg
- */
-#define	ARMV8_PMU_OVSR_MASK		0xffffffff	/* Mask for writable bits */
-#define	ARMV8_PMU_OVERFLOWED_MASK	ARMV8_PMU_OVSR_MASK
-
-/*
- * PMXEVTYPER: Event selection reg
- */
-#define	ARMV8_PMU_EVTYPE_MASK	0xc800ffff	/* Mask for writable bits */
-#define	ARMV8_PMU_EVTYPE_EVENT	0xffff		/* Mask for EVENT bits */
-
-/*
- * PMUv3 event types: required events
- */
-#define ARMV8_PMUV3_PERFCTR_SW_INCR				0x00
-#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL			0x03
-#define ARMV8_PMUV3_PERFCTR_L1D_CACHE				0x04
-#define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED				0x10
-#define ARMV8_PMUV3_PERFCTR_CPU_CYCLES				0x11
-#define ARMV8_PMUV3_PERFCTR_BR_PRED				0x12
-
-/*
- * Event filters for PMUv3
- */
-#define	ARMV8_PMU_EXCLUDE_EL1	(1 << 31)
-#define	ARMV8_PMU_EXCLUDE_EL0	(1 << 30)
-#define	ARMV8_PMU_INCLUDE_EL2	(1 << 27)
-
-/*
- * PMUSERENR: user enable reg
- */
-#define ARMV8_PMU_USERENR_MASK	0xf		/* Mask for writable bits */
-#define ARMV8_PMU_USERENR_EN	(1 << 0) /* PMU regs can be accessed at EL0 */
-#define ARMV8_PMU_USERENR_SW	(1 << 1) /* PMSWINC can be written at EL0 */
-#define ARMV8_PMU_USERENR_CR	(1 << 2) /* Cycle counter can be read at EL0 */
-#define ARMV8_PMU_USERENR_ER	(1 << 3) /* Event counter can be read@EL0 */
-
 #ifdef CONFIG_PERF_EVENTS
 struct pt_regs;
 extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 1606c6b2a280..b50696a5875a 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -33,7 +33,6 @@ arm64-obj-$(CONFIG_FUNCTION_TRACER)	+= ftrace.o entry-ftrace.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_ARM64_MODULE_PLTS)	+= module-plts.o
 arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o perf_callchain.o
-arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
 arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
 arm64-obj-$(CONFIG_CPU_PM)		+= sleep.o suspend.o
 arm64-obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 93651907874f..bd2b1b1cb1b6 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -12,6 +12,7 @@ config ARM_PMU
 	  Say y if you want to use CPU performance monitors on ARM-based
 	  systems.
 
+
 config QCOM_L2_PMU
 	bool "Qualcomm Technologies L2-cache PMU"
 	depends on ARCH_QCOM && ARM64 && PERF_EVENTS && ACPI
@@ -21,6 +22,14 @@ config QCOM_L2_PMU
 	  Adds the L2 cache PMU into the perf events subsystem for
 	  monitoring L2 cache events.
 
+config ARM_PMUV3
+	depends on HW_PERF_EVENTS && ARM64
+	bool "ARM PMUv3 support"
+	default y
+	help
+	  Say y if you want to use CPU performance monitors on ARMv8
+	  systems that implement the PMUv3 architecture.
+
 config XGENE_PMU
         depends on PERF_EVENTS && ARCH_XGENE
         bool "APM X-Gene SoC PMU"
diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
index ef24833c94a8..645a59c2d6ee 100644
--- a/drivers/perf/Makefile
+++ b/drivers/perf/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_ARM_PMU) += arm_pmu.o
+obj-$(CONFIG_ARM_PMUV3) += arm_pmuv3.o
 obj-$(CONFIG_QCOM_L2_PMU)	+= qcom_l2_pmu.o
 obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
diff --git a/arch/arm64/kernel/perf_event.c b/drivers/perf/arm_pmuv3.c
similarity index 99%
rename from arch/arm64/kernel/perf_event.c
rename to drivers/perf/arm_pmuv3.c
index 57ae9d9ed9bb..ac4e6dfc9486 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/drivers/perf/arm_pmuv3.c
@@ -27,6 +27,7 @@
 #include <linux/acpi.h>
 #include <linux/of.h>
 #include <linux/perf/arm_pmu.h>
+#include <linux/perf/arm_pmuv3.h>
 #include <linux/platform_device.h>
 
 /*
diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
index 92e7e97ca8ff..8e9927524c81 100644
--- a/include/kvm/arm_pmu.h
+++ b/include/kvm/arm_pmu.h
@@ -19,7 +19,7 @@
 #define __ASM_ARM_KVM_PMU_H
 
 #include <linux/perf_event.h>
-#include <asm/perf_event.h>
+#include <linux/perf/arm_pmuv3.h>
 
 #define ARMV8_PMU_CYCLE_IDX		(ARMV8_PMU_MAX_COUNTERS - 1)
 
diff --git a/include/linux/perf/arm_pmuv3.h b/include/linux/perf/arm_pmuv3.h
new file mode 100644
index 000000000000..119b0decc392
--- /dev/null
+++ b/include/linux/perf/arm_pmuv3.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PERF_ARM_PMUV3_H
+#define __PERF_ARM_PMUV3_H
+
+#define	ARMV8_PMU_MAX_COUNTERS	32
+#define	ARMV8_PMU_COUNTER_MASK	(ARMV8_PMU_MAX_COUNTERS - 1)
+
+/*
+ * Per-CPU PMCR: config reg
+ */
+#define ARMV8_PMU_PMCR_E	(1 << 0) /* Enable all counters */
+#define ARMV8_PMU_PMCR_P	(1 << 1) /* Reset all counters */
+#define ARMV8_PMU_PMCR_C	(1 << 2) /* Cycle counter reset */
+#define ARMV8_PMU_PMCR_D	(1 << 3) /* CCNT counts every 64th cpu cycle */
+#define ARMV8_PMU_PMCR_X	(1 << 4) /* Export to ETM */
+#define ARMV8_PMU_PMCR_DP	(1 << 5) /* Disable CCNT if non-invasive debug*/
+#define ARMV8_PMU_PMCR_LC	(1 << 6) /* Overflow on 64 bit cycle counter */
+#define	ARMV8_PMU_PMCR_N_SHIFT	11	 /* Number of counters supported */
+#define	ARMV8_PMU_PMCR_N_MASK	0x1f
+#define	ARMV8_PMU_PMCR_MASK	0x7f	 /* Mask for writable bits */
+
+/*
+ * PMOVSR: counters overflow flag status reg
+ */
+#define	ARMV8_PMU_OVSR_MASK		0xffffffff	/* Mask for writable bits */
+#define	ARMV8_PMU_OVERFLOWED_MASK	ARMV8_PMU_OVSR_MASK
+
+/*
+ * PMXEVTYPER: Event selection reg
+ */
+#define	ARMV8_PMU_EVTYPE_MASK	0xc800ffff	/* Mask for writable bits */
+#define	ARMV8_PMU_EVTYPE_EVENT	0xffff		/* Mask for EVENT bits */
+
+/*
+ * PMUv3 event types: required events
+ */
+#define ARMV8_PMUV3_PERFCTR_SW_INCR				0x00
+#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL			0x03
+#define ARMV8_PMUV3_PERFCTR_L1D_CACHE				0x04
+#define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED				0x10
+#define ARMV8_PMUV3_PERFCTR_CPU_CYCLES				0x11
+#define ARMV8_PMUV3_PERFCTR_BR_PRED				0x12
+
+/*
+ * Event filters for PMUv3
+ */
+#define	ARMV8_PMU_EXCLUDE_EL1	(1 << 31)
+#define	ARMV8_PMU_EXCLUDE_EL0	(1 << 30)
+#define	ARMV8_PMU_INCLUDE_EL2	(1 << 27)
+
+/*
+ * PMUSERENR: user enable reg
+ */
+#define ARMV8_PMU_USERENR_MASK	0xf		/* Mask for writable bits */
+#define ARMV8_PMU_USERENR_EN	(1 << 0) /* PMU regs can be accessed at EL0 */
+#define ARMV8_PMU_USERENR_SW	(1 << 1) /* PMSWINC can be written at EL0 */
+#define ARMV8_PMU_USERENR_CR	(1 << 2) /* Cycle counter can be read at EL0 */
+#define ARMV8_PMU_USERENR_ER	(1 << 3) /* Event counter can be read@EL0 */
+
+#endif
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/4] arm64: perf: Abstract system register accesses away
  2017-03-24 12:15 [PATCH 0/4] perf: Enabling PMUv3 on 32bit ARM systems Marc Zyngier
  2017-03-24 12:15 ` [PATCH 1/4] arm64: perf: Move PMUv3 driver to drivers/perf Marc Zyngier
@ 2017-03-24 12:15 ` Marc Zyngier
  2017-03-24 12:15 ` [PATCH 3/4] ARM: perf: Allow the use of the PMUv3 driver on 32bit ARM Marc Zyngier
  2017-03-24 12:15 ` [PATCH 4/4] ARM: mach-virt: Select PMUv3 driver by default Marc Zyngier
  3 siblings, 0 replies; 7+ messages in thread
From: Marc Zyngier @ 2017-03-24 12:15 UTC (permalink / raw)
  To: linux-arm-kernel

As we want to enable 32bit support, we need to distanciate the
PMUv3 driver from the AArch64 system register names.

This patch moves all system register accesses to an architecture
specific include file, allowing the 32bit counterpart to be
slotted in at a later time.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/arm_pmuv3.h | 102 +++++++++++++++++++++++++++++++++++++
 drivers/perf/arm_pmuv3.c           |  35 +++++++------
 include/linux/perf/arm_pmuv3.h     |   2 +
 3 files changed, 121 insertions(+), 18 deletions(-)
 create mode 100644 arch/arm64/include/asm/arm_pmuv3.h

diff --git a/arch/arm64/include/asm/arm_pmuv3.h b/arch/arm64/include/asm/arm_pmuv3.h
new file mode 100644
index 000000000000..7b01787fb8fd
--- /dev/null
+++ b/arch/arm64/include/asm/arm_pmuv3.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ASM_PMUV3_H
+#define __ASM_PMUV3_H
+
+#include <asm/sysreg.h>
+
+static inline void write_pmcr(u32 val)
+{
+	write_sysreg(val, pmcr_el0);
+}
+
+static inline u32 read_pmcr(void)
+{
+	return read_sysreg(pmcr_el0);
+}
+
+static inline void write_pmselr(u32 val)
+{
+	write_sysreg(val, pmselr_el0);
+}
+
+static inline void write_pmccntr(u64 val)
+{
+	write_sysreg(val, pmccntr_el0);
+}
+
+static inline u64 read_pmccntr(void)
+{
+	return read_sysreg(pmccntr_el0);
+}
+
+static inline void write_pmxevcntr(u32 val)
+{
+	write_sysreg(val, pmxevcntr_el0);
+}
+
+static inline u32 read_pmxevcntr(void)
+{
+	return read_sysreg(pmxevcntr_el0);
+}
+
+static inline void write_pmxevtyper(u32 val)
+{
+	write_sysreg(val, pmxevtyper_el0);
+}
+
+static inline void write_pmcntenset(u32 val)
+{
+	write_sysreg(val, pmcntenset_el0);
+}
+
+static inline void write_pmcntenclr(u32 val)
+{
+	write_sysreg(val, pmcntenclr_el0);
+}
+
+static inline void write_pmintenset(u32 val)
+{
+	write_sysreg(val, pmintenset_el1);
+}
+
+static inline void write_pmintenclr(u32 val)
+{
+	write_sysreg(val, pmintenclr_el1);
+}
+
+static inline void write_pmovsclr(u32 val)
+{
+	write_sysreg(val, pmovsclr_el0);
+}
+
+static inline u32 read_pmovsclr(void)
+{
+	return read_sysreg(pmovsclr_el0);
+}
+
+static inline u32 read_pmceid0(void)
+{
+	return read_sysreg(pmceid0_el0);
+}
+
+static inline u32 read_pmceid1(void)
+{
+	return read_sysreg(pmceid1_el0);
+}
+
+#endif
diff --git a/drivers/perf/arm_pmuv3.c b/drivers/perf/arm_pmuv3.c
index ac4e6dfc9486..55486dcd2d5b 100644
--- a/drivers/perf/arm_pmuv3.c
+++ b/drivers/perf/arm_pmuv3.c
@@ -21,7 +21,6 @@
 
 #include <asm/irq_regs.h>
 #include <asm/perf_event.h>
-#include <asm/sysreg.h>
 #include <asm/virt.h>
 
 #include <linux/acpi.h>
@@ -556,14 +555,14 @@ static struct attribute_group armv8_pmuv3_format_attr_group = {
 
 static inline u32 armv8pmu_pmcr_read(void)
 {
-	return read_sysreg(pmcr_el0);
+	return read_pmcr();
 }
 
 static inline void armv8pmu_pmcr_write(u32 val)
 {
 	val &= ARMV8_PMU_PMCR_MASK;
 	isb();
-	write_sysreg(val, pmcr_el0);
+	write_pmcr(val);
 }
 
 static inline int armv8pmu_has_overflowed(u32 pmovsr)
@@ -585,7 +584,7 @@ static inline int armv8pmu_counter_has_overflowed(u32 pmnc, int idx)
 static inline int armv8pmu_select_counter(int idx)
 {
 	u32 counter = ARMV8_IDX_TO_COUNTER(idx);
-	write_sysreg(counter, pmselr_el0);
+	write_pmselr(counter);
 	isb();
 
 	return idx;
@@ -602,9 +601,9 @@ static inline u32 armv8pmu_read_counter(struct perf_event *event)
 		pr_err("CPU%u reading wrong counter %d\n",
 			smp_processor_id(), idx);
 	else if (idx == ARMV8_IDX_CYCLE_COUNTER)
-		value = read_sysreg(pmccntr_el0);
+		value = read_pmccntr();
 	else if (armv8pmu_select_counter(idx) == idx)
-		value = read_sysreg(pmxevcntr_el0);
+		value = read_pmxevcntr();
 
 	return value;
 }
@@ -626,47 +625,47 @@ static inline void armv8pmu_write_counter(struct perf_event *event, u32 value)
 		 */
 		u64 value64 = 0xffffffff00000000ULL | value;
 
-		write_sysreg(value64, pmccntr_el0);
+		write_pmccntr(value64);
 	} else if (armv8pmu_select_counter(idx) == idx)
-		write_sysreg(value, pmxevcntr_el0);
+		write_pmxevcntr(value);
 }
 
 static inline void armv8pmu_write_evtype(int idx, u32 val)
 {
 	if (armv8pmu_select_counter(idx) == idx) {
 		val &= ARMV8_PMU_EVTYPE_MASK;
-		write_sysreg(val, pmxevtyper_el0);
+		write_pmxevtyper(val);
 	}
 }
 
 static inline int armv8pmu_enable_counter(int idx)
 {
 	u32 counter = ARMV8_IDX_TO_COUNTER(idx);
-	write_sysreg(BIT(counter), pmcntenset_el0);
+	write_pmcntenset(BIT(counter));
 	return idx;
 }
 
 static inline int armv8pmu_disable_counter(int idx)
 {
 	u32 counter = ARMV8_IDX_TO_COUNTER(idx);
-	write_sysreg(BIT(counter), pmcntenclr_el0);
+	write_pmcntenclr(BIT(counter));
 	return idx;
 }
 
 static inline int armv8pmu_enable_intens(int idx)
 {
 	u32 counter = ARMV8_IDX_TO_COUNTER(idx);
-	write_sysreg(BIT(counter), pmintenset_el1);
+	write_pmintenset(BIT(counter));
 	return idx;
 }
 
 static inline int armv8pmu_disable_intens(int idx)
 {
 	u32 counter = ARMV8_IDX_TO_COUNTER(idx);
-	write_sysreg(BIT(counter), pmintenclr_el1);
+	write_pmintenclr(BIT(counter));
 	isb();
 	/* Clear the overflow flag in case an interrupt is pending. */
-	write_sysreg(BIT(counter), pmovsclr_el0);
+	write_pmovsclr(BIT(counter));
 	isb();
 
 	return idx;
@@ -677,11 +676,11 @@ static inline u32 armv8pmu_getreset_flags(void)
 	u32 value;
 
 	/* Read */
-	value = read_sysreg(pmovsclr_el0);
+	value = read_pmovsclr();
 
 	/* Write to clear flags */
 	value &= ARMV8_PMU_OVSR_MASK;
-	write_sysreg(value, pmovsclr_el0);
+	write_pmovsclr(value);
 
 	return value;
 }
@@ -970,8 +969,8 @@ static void __armv8pmu_probe_pmu(void *info)
 	/* Add the CPU cycles counter */
 	cpu_pmu->num_events += 1;
 
-	pmceid[0] = read_sysreg(pmceid0_el0);
-	pmceid[1] = read_sysreg(pmceid1_el0);
+	pmceid[0] = read_pmceid0();
+	pmceid[1] = read_pmceid1();
 
 	bitmap_from_u32array(cpu_pmu->pmceid_bitmap,
 			     ARMV8_PMUV3_MAX_COMMON_EVENTS, pmceid,
diff --git a/include/linux/perf/arm_pmuv3.h b/include/linux/perf/arm_pmuv3.h
index 119b0decc392..e0b1ae016fa5 100644
--- a/include/linux/perf/arm_pmuv3.h
+++ b/include/linux/perf/arm_pmuv3.h
@@ -17,6 +17,8 @@
 #ifndef __PERF_ARM_PMUV3_H
 #define __PERF_ARM_PMUV3_H
 
+#include <asm/arm_pmuv3.h>
+
 #define	ARMV8_PMU_MAX_COUNTERS	32
 #define	ARMV8_PMU_COUNTER_MASK	(ARMV8_PMU_MAX_COUNTERS - 1)
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/4] ARM: perf: Allow the use of the PMUv3 driver on 32bit ARM
  2017-03-24 12:15 [PATCH 0/4] perf: Enabling PMUv3 on 32bit ARM systems Marc Zyngier
  2017-03-24 12:15 ` [PATCH 1/4] arm64: perf: Move PMUv3 driver to drivers/perf Marc Zyngier
  2017-03-24 12:15 ` [PATCH 2/4] arm64: perf: Abstract system register accesses away Marc Zyngier
@ 2017-03-24 12:15 ` Marc Zyngier
  2017-05-04 11:00   ` Vladimir Murzin
  2017-03-24 12:15 ` [PATCH 4/4] ARM: mach-virt: Select PMUv3 driver by default Marc Zyngier
  3 siblings, 1 reply; 7+ messages in thread
From: Marc Zyngier @ 2017-03-24 12:15 UTC (permalink / raw)
  To: linux-arm-kernel

The only thing stopping the PMUv3 driver from compiling on 32bit
is the lack of defined system registers names. This is easily
solved by providing the sysreg accessors and updating the Kconfig entry.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/arm_pmuv3.h | 115 +++++++++++++++++++++++++++++++++++++++
 drivers/perf/Kconfig             |   4 +-
 2 files changed, 117 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/include/asm/arm_pmuv3.h

diff --git a/arch/arm/include/asm/arm_pmuv3.h b/arch/arm/include/asm/arm_pmuv3.h
new file mode 100644
index 000000000000..df14de3d7bdf
--- /dev/null
+++ b/arch/arm/include/asm/arm_pmuv3.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ASM_PMUV3_H
+#define __ASM_PMUV3_H
+
+#include <asm/cp15.h>
+
+#define pmcr		__ACCESS_CP15(c9, 0, c12, 0)
+#define pmselr		__ACCESS_CP15(c9, 0, c12, 5)
+#define pmccntr		__ACCESS_CP15_64(0, c9)
+#define pmxevcntr	__ACCESS_CP15(c9, 0, c13, 2)
+#define pmxevtyper	__ACCESS_CP15(c9, 0, c13, 1)
+#define pmcntenset	__ACCESS_CP15(c9, 0, c12, 1)
+#define pmcntenclr	__ACCESS_CP15(c9, 0, c12, 2)
+#define pmintenset	__ACCESS_CP15(c9, 0, c12, 1)
+#define pmintenclr	__ACCESS_CP15(c9, 0, c12, 2)
+#define pmovsclr	__ACCESS_CP15(c9, 0, c12, 3)
+#define pmceid0		__ACCESS_CP15(c9, 0, c12, 6)
+#define pmceid1		__ACCESS_CP15(c9, 0, c12, 7)
+
+static inline void write_pmcr(u32 val)
+{
+	write_sysreg(val, pmcr);
+}
+
+static inline u32 read_pmcr(void)
+{
+	return read_sysreg(pmcr);
+}
+
+static inline void write_pmselr(u32 val)
+{
+	write_sysreg(val, pmselr);
+}
+
+static inline void write_pmccntr(u64 val)
+{
+	write_sysreg(val, pmccntr);
+}
+
+static inline u64 read_pmccntr(void)
+{
+	return read_sysreg(pmccntr);
+}
+
+static inline void write_pmxevcntr(u32 val)
+{
+	write_sysreg(val, pmxevcntr);
+}
+
+static inline u32 read_pmxevcntr(void)
+{
+	return read_sysreg(pmxevcntr);
+}
+
+static inline void write_pmxevtyper(u32 val)
+{
+	write_sysreg(val, pmxevtyper);
+}
+
+static inline void write_pmcntenset(u32 val)
+{
+	write_sysreg(val, pmcntenset);
+}
+
+static inline void write_pmcntenclr(u32 val)
+{
+	write_sysreg(val, pmcntenclr);
+}
+
+static inline void write_pmintenset(u32 val)
+{
+	write_sysreg(val, pmintenset);
+}
+
+static inline void write_pmintenclr(u32 val)
+{
+	write_sysreg(val, pmintenclr);
+}
+
+static inline void write_pmovsclr(u32 val)
+{
+	write_sysreg(val, pmovsclr);
+}
+
+static inline u32 read_pmovsclr(void)
+{
+	return read_sysreg(pmovsclr);
+}
+
+static inline u32 read_pmceid0(void)
+{
+	return read_sysreg(pmceid0);
+}
+
+static inline u32 read_pmceid1(void)
+{
+	return read_sysreg(pmceid1);
+}
+
+#endif
diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index bd2b1b1cb1b6..5b98a24c2b34 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -23,9 +23,9 @@ config QCOM_L2_PMU
 	  monitoring L2 cache events.
 
 config ARM_PMUV3
-	depends on HW_PERF_EVENTS && ARM64
+	depends on HW_PERF_EVENTS && ((ARM && CPU_V7) || ARM64)
 	bool "ARM PMUv3 support"
-	default y
+	default ARM64
 	help
 	  Say y if you want to use CPU performance monitors on ARMv8
 	  systems that implement the PMUv3 architecture.
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/4] ARM: mach-virt: Select PMUv3 driver by default
  2017-03-24 12:15 [PATCH 0/4] perf: Enabling PMUv3 on 32bit ARM systems Marc Zyngier
                   ` (2 preceding siblings ...)
  2017-03-24 12:15 ` [PATCH 3/4] ARM: perf: Allow the use of the PMUv3 driver on 32bit ARM Marc Zyngier
@ 2017-03-24 12:15 ` Marc Zyngier
  3 siblings, 0 replies; 7+ messages in thread
From: Marc Zyngier @ 2017-03-24 12:15 UTC (permalink / raw)
  To: linux-arm-kernel

Since 32bit guests are not unlikely to run on an ARMv8 host,
let's select the PMUv3 driver, which allows the PMU to be used
on such systems.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0d4e71b42c77..60bb0e0a807d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -711,6 +711,7 @@ config ARCH_VIRT
 	select ARM_GIC_V3
 	select ARM_GIC_V3_ITS if PCI
 	select ARM_PSCI
+	select ARM_PMUV3 if PERF_EVENTS
 	select HAVE_ARM_ARCH_TIMER
 
 #
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/4] ARM: perf: Allow the use of the PMUv3 driver on 32bit ARM
  2017-03-24 12:15 ` [PATCH 3/4] ARM: perf: Allow the use of the PMUv3 driver on 32bit ARM Marc Zyngier
@ 2017-05-04 11:00   ` Vladimir Murzin
  2017-05-04 11:31     ` Marc Zyngier
  0 siblings, 1 reply; 7+ messages in thread
From: Vladimir Murzin @ 2017-05-04 11:00 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Marc,

On 24/03/17 12:15, Marc Zyngier wrote:
> The only thing stopping the PMUv3 driver from compiling on 32bit
> is the lack of defined system registers names. This is easily
> solved by providing the sysreg accessors and updating the Kconfig entry.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm/include/asm/arm_pmuv3.h | 115 +++++++++++++++++++++++++++++++++++++++
>  drivers/perf/Kconfig             |   4 +-
>  2 files changed, 117 insertions(+), 2 deletions(-)
>  create mode 100644 arch/arm/include/asm/arm_pmuv3.h
> 
> diff --git a/arch/arm/include/asm/arm_pmuv3.h b/arch/arm/include/asm/arm_pmuv3.h
> new file mode 100644
> index 000000000000..df14de3d7bdf
> --- /dev/null
> +++ b/arch/arm/include/asm/arm_pmuv3.h
> @@ -0,0 +1,115 @@
> +/*
> + * Copyright (C) 2012 ARM Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef __ASM_PMUV3_H
> +#define __ASM_PMUV3_H
> +
> +#include <asm/cp15.h>
> +
> +#define pmcr		__ACCESS_CP15(c9, 0, c12, 0)
> +#define pmselr		__ACCESS_CP15(c9, 0, c12, 5)
> +#define pmccntr		__ACCESS_CP15_64(0, c9)
> +#define pmxevcntr	__ACCESS_CP15(c9, 0, c13, 2)
> +#define pmxevtyper	__ACCESS_CP15(c9, 0, c13, 1)
> +#define pmcntenset	__ACCESS_CP15(c9, 0, c12, 1)
> +#define pmcntenclr	__ACCESS_CP15(c9, 0, c12, 2)
> +#define pmintenset	__ACCESS_CP15(c9, 0, c12, 1)

Encoding is not right here

To access the PMINTENSET:

MRC p15,0,<Rt>,c9,c14,1 ; Read PMINTENSET into Rt

MCR p15,0,<Rt>,c9,c14,1 ; Write Rt to PMINTENSET


> +#define pmintenclr	__ACCESS_CP15(c9, 0, c12, 2)

Ditto

To access the PMINTENCLR:

MRC p15,0,<Rt>,c9,c14,2 ; Read PMINTENCLR into Rt

MCR p15,0,<Rt>,c9,c14,2 ; Write Rt to PMINTENCLR


> +#define pmovsclr	__ACCESS_CP15(c9, 0, c12, 3)

Nit: in 32-bit world it is named as PMOVSR.

> +#define pmceid0		__ACCESS_CP15(c9, 0, c12, 6)
> +#define pmceid1		__ACCESS_CP15(c9, 0, c12, 7)

Can all these defines be done in uppercase to be in align with existent users
of __ACCESS_CP15() macro?

Thanks
Vladimir

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 3/4] ARM: perf: Allow the use of the PMUv3 driver on 32bit ARM
  2017-05-04 11:00   ` Vladimir Murzin
@ 2017-05-04 11:31     ` Marc Zyngier
  0 siblings, 0 replies; 7+ messages in thread
From: Marc Zyngier @ 2017-05-04 11:31 UTC (permalink / raw)
  To: linux-arm-kernel

On 04/05/17 12:00, Vladimir Murzin wrote:
> Hi Marc,
> 
> On 24/03/17 12:15, Marc Zyngier wrote:
>> The only thing stopping the PMUv3 driver from compiling on 32bit
>> is the lack of defined system registers names. This is easily
>> solved by providing the sysreg accessors and updating the Kconfig entry.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  arch/arm/include/asm/arm_pmuv3.h | 115 +++++++++++++++++++++++++++++++++++++++
>>  drivers/perf/Kconfig             |   4 +-
>>  2 files changed, 117 insertions(+), 2 deletions(-)
>>  create mode 100644 arch/arm/include/asm/arm_pmuv3.h
>>
>> diff --git a/arch/arm/include/asm/arm_pmuv3.h b/arch/arm/include/asm/arm_pmuv3.h
>> new file mode 100644
>> index 000000000000..df14de3d7bdf
>> --- /dev/null
>> +++ b/arch/arm/include/asm/arm_pmuv3.h
>> @@ -0,0 +1,115 @@
>> +/*
>> + * Copyright (C) 2012 ARM Ltd.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#ifndef __ASM_PMUV3_H
>> +#define __ASM_PMUV3_H
>> +
>> +#include <asm/cp15.h>
>> +
>> +#define pmcr		__ACCESS_CP15(c9, 0, c12, 0)
>> +#define pmselr		__ACCESS_CP15(c9, 0, c12, 5)
>> +#define pmccntr		__ACCESS_CP15_64(0, c9)
>> +#define pmxevcntr	__ACCESS_CP15(c9, 0, c13, 2)
>> +#define pmxevtyper	__ACCESS_CP15(c9, 0, c13, 1)
>> +#define pmcntenset	__ACCESS_CP15(c9, 0, c12, 1)
>> +#define pmcntenclr	__ACCESS_CP15(c9, 0, c12, 2)
>> +#define pmintenset	__ACCESS_CP15(c9, 0, c12, 1)
> 
> Encoding is not right here
> 
> To access the PMINTENSET:
> 
> MRC p15,0,<Rt>,c9,c14,1 ; Read PMINTENSET into Rt
> 
> MCR p15,0,<Rt>,c9,c14,1 ; Write Rt to PMINTENSET
> 
> 
>> +#define pmintenclr	__ACCESS_CP15(c9, 0, c12, 2)
> 
> Ditto
> 
> To access the PMINTENCLR:
> 
> MRC p15,0,<Rt>,c9,c14,2 ; Read PMINTENCLR into Rt
> 
> MCR p15,0,<Rt>,c9,c14,2 ; Write Rt to PMINTENCLR

Arghh, -ECOPYPASTE. Thanks for the heads up!

> 
> 
>> +#define pmovsclr	__ACCESS_CP15(c9, 0, c12, 3)
> 
> Nit: in 32-bit world it is named as PMOVSR.
> 
>> +#define pmceid0		__ACCESS_CP15(c9, 0, c12, 6)
>> +#define pmceid1		__ACCESS_CP15(c9, 0, c12, 7)
> 
> Can all these defines be done in uppercase to be in align with existent users
> of __ACCESS_CP15() macro?

Sure, that shouldn't be an issue.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2017-05-04 11:31 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-24 12:15 [PATCH 0/4] perf: Enabling PMUv3 on 32bit ARM systems Marc Zyngier
2017-03-24 12:15 ` [PATCH 1/4] arm64: perf: Move PMUv3 driver to drivers/perf Marc Zyngier
2017-03-24 12:15 ` [PATCH 2/4] arm64: perf: Abstract system register accesses away Marc Zyngier
2017-03-24 12:15 ` [PATCH 3/4] ARM: perf: Allow the use of the PMUv3 driver on 32bit ARM Marc Zyngier
2017-05-04 11:00   ` Vladimir Murzin
2017-05-04 11:31     ` Marc Zyngier
2017-03-24 12:15 ` [PATCH 4/4] ARM: mach-virt: Select PMUv3 driver by default Marc Zyngier

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.