lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220816130221.885920-1-peternewman@google.com>
Date:   Tue, 16 Aug 2022 15:02:21 +0200
From:   Peter Newman <peternewman@...gle.com>
To:     linux-kernel@...r.kernel.org
Cc:     mark.rutland@....com, peterz@...radead.org, will@...nel.org,
        Stephane Eranian <eranian@...gle.com>,
        Peter Newman <peternewman@...gle.com>
Subject: [PATCH v3] perf/arm: adjust hwevents mappings on boot

From: Stephane Eranian <eranian@...gle.com>

The mapping of perf_events generic hardware events to actual PMU events on
ARM PMUv3 may not always be correct. This is in particular true for the
PERF_COUNT_HW_BRANCH_INSTRUCTIONS event. Although the mapping points to an
architected event, it may not always be available. This can be seen with a
simple:

$ perf stat -e branches sleep 0
 Performance counter stats for 'sleep 0':

   <not supported>      branches

       0.001401081 seconds time elapsed

Yet the hardware does have an event that could be used for branches.  This
patch fixes the problem by dynamically validating the generic hardware
events against the supported architected events. If a mapping is wrong it
can be replaced it with another. This is done for the event above at boot
time.

And with that:

$ perf stat -e branches sleep 0

 Performance counter stats for 'sleep 0':

           166,739      branches

       0.000832163 seconds time elapsed

Signed-off-by: Stephane Eranian <eranian@...gle.com>
Co-developed-by: Peter Newman <peternewman@...gle.com>
Signed-off-by: Peter Newman <peternewman@...gle.com>
---

v2: https://lore.kernel.org/lkml/20220324181458.3216262-1-eranian@google.com/

since v2, removed prints per Will's suggestion

 arch/arm64/kernel/perf_event.c | 36 +++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index cb69ff1e6138..945c31e3f3e3 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -39,7 +39,7 @@
  * be supported on any given implementation. Unsupported events will
  * be disabled at run-time based on the PMCEID registers.
  */
-static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = {
+static unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = {
 	PERF_MAP_ALL_UNSUPPORTED,
 	[PERF_COUNT_HW_CPU_CYCLES]		= ARMV8_PMUV3_PERFCTR_CPU_CYCLES,
 	[PERF_COUNT_HW_INSTRUCTIONS]		= ARMV8_PMUV3_PERFCTR_INST_RETIRED,
@@ -1232,6 +1232,37 @@ static void armv8_pmu_register_sysctl_table(void)
 		register_sysctl("kernel", armv8_pmu_sysctl_table);
 }
 
+static void armv8pmu_fixup_perf_map(struct arm_pmu *cpu_pmu)
+{
+	int i, code;
+	unsigned *map = armv8_pmuv3_perf_map;
+
+	for (i = 0; i < PERF_COUNT_HW_MAX; i++) {
+retry:
+		code = map[i];
+		if (code == HW_OP_UNSUPPORTED)
+			continue;
+
+		if (test_bit(map[i], cpu_pmu->pmceid_bitmap))
+			continue;
+		/*
+		 * mapping does not exist,
+		 * let's see if we can fix it
+		 */
+		switch (i) {
+		case PERF_COUNT_HW_BRANCH_INSTRUCTIONS:
+			if (code == ARMV8_PMUV3_PERFCTR_PC_WRITE_RETIRED) {
+				map[i] = ARMV8_PMUV3_PERFCTR_BR_RETIRED;
+				goto retry;
+			}
+			break;
+		default:
+			map[i] = HW_OP_UNSUPPORTED;
+			break;
+		}
+	}
+}
+
 static int armv8_pmu_init(struct arm_pmu *cpu_pmu, char *name,
 			  int (*map_event)(struct perf_event *event),
 			  const struct attribute_group *events,
@@ -1259,6 +1290,9 @@ static int armv8_pmu_init(struct arm_pmu *cpu_pmu, char *name,
 
 	cpu_pmu->name			= name;
 	cpu_pmu->map_event		= map_event;
+
+	armv8pmu_fixup_perf_map(cpu_pmu);
+
 	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = events ?
 			events : &armv8_pmuv3_events_attr_group;
 	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = format ?

base-commit: 568035b01cfb107af8d2e4bd2fb9aea22cf5b868
-- 
2.37.1.595.g718a3a8f04-goog

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ