[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220712051404.2546851-1-anshuman.khandual@arm.com>
Date: Tue, 12 Jul 2022 10:44:04 +0530
From: Anshuman Khandual <anshuman.khandual@....com>
To: linux-arm-kernel@...ts.infradead.org
Cc: german.gomez@....com, james.clark@....com, suzuki.poulose@....com,
Anshuman Khandual <anshuman.khandual@....com>,
Will Deacon <will@...nel.org>,
Mark Rutland <mark.rutland@....com>,
linux-kernel@...r.kernel.org
Subject: [PATCH] drivers/perf: arm_spe: Fix consistency of SYS_PMSCR_EL1.CX
The arm_spe_pmu driver will enable SYS_PMSCR_EL1.CX in order to add CONTEXT
packets into the traces, if the owner of the perf event runs with required
capabilities i.e CAP_PERFMON or CAP_SYS_ADMIN via perfmon_capable() helper.
The value of this bit is computed in the arm_spe_event_to_pmscr() function
but the check for capabilities happens in the pmu event init callback i.e
arm_spe_pmu_event_init(). This suggests that the value of the CX bit should
remain consistent for the duration of the perf session.
However, the function arm_spe_event_to_pmscr() may be called later during
the event start callback i.e arm_spe_pmu_start() when the "current" process
is not the owner of the perf session, hence the CX bit setting is currently
not consistent.
One way to fix this, is by caching the required value of the CX bit during
the initialization of the PMU event, so that it remains consistent for the
duration of the session. It uses currently unused 'event->hw.flags' element
to cache perfmon_capable() value, which can be referred during event start
callback to compute SYS_PMSCR_EL1.CX. This ensures consistent availability
of context packets in the trace as per event owner capabilities.
Cc: Will Deacon <will@...nel.org>
Cc: Mark Rutland <mark.rutland@....com>
Cc: linux-arm-kernel@...ts.infradead.org
Cc: linux-kernel@...r.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual@....com>
---
This applies on v5.19-rc6 and built on an earlier version posted by German
https://lore.kernel.org/all/20220117124432.3119132-1-german.gomez@arm.com/
drivers/perf/arm_spe_pmu.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c
index db670b265897..011e98428233 100644
--- a/drivers/perf/arm_spe_pmu.c
+++ b/drivers/perf/arm_spe_pmu.c
@@ -39,6 +39,26 @@
#include <asm/mmu.h>
#include <asm/sysreg.h>
+/*
+ * event.hw.flags remain unused for events created for this
+ * PMU driver. A single bit there i.e BIT(0), could be used
+ * to remember initiating process's perfmon_capable() value
+ * which can be subsequently used to enable SYS_PMSCR_EL.CX
+ * thus enabling context information in the trace.
+ */
+#define SPE_PMU_HW_FLAGS_CX BIT(0)
+
+static void event_hw_flags_set_cx(struct perf_event *event)
+{
+ if (perfmon_capable())
+ event->hw.flags |= SPE_PMU_HW_FLAGS_CX;
+}
+
+static bool event_hw_flags_has_cx(struct perf_event *event)
+{
+ return !!(event->hw.flags & SPE_PMU_HW_FLAGS_CX);
+}
+
#define ARM_SPE_BUF_PAD_BYTE 0
struct arm_spe_pmu_buf {
@@ -272,7 +292,7 @@ static u64 arm_spe_event_to_pmscr(struct perf_event *event)
if (!attr->exclude_kernel)
reg |= BIT(SYS_PMSCR_EL1_E1SPE_SHIFT);
- if (IS_ENABLED(CONFIG_PID_IN_CONTEXTIDR) && perfmon_capable())
+ if (IS_ENABLED(CONFIG_PID_IN_CONTEXTIDR) && event_hw_flags_has_cx(event))
reg |= BIT(SYS_PMSCR_EL1_CX_SHIFT);
return reg;
@@ -710,7 +730,8 @@ static int arm_spe_pmu_event_init(struct perf_event *event)
return -EOPNOTSUPP;
reg = arm_spe_event_to_pmscr(event);
- if (!perfmon_capable() &&
+ event_hw_flags_set_cx(event);
+ if (!event_hw_flags_has_cx(event) &&
(reg & (BIT(SYS_PMSCR_EL1_PA_SHIFT) |
BIT(SYS_PMSCR_EL1_CX_SHIFT) |
BIT(SYS_PMSCR_EL1_PCT_SHIFT))))
--
2.25.1
Powered by blists - more mailing lists