Patch "drivers/perf: arm_spe: Fix consistency of SYS_PMSCR_EL1.CX" has been added to the 5.10-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    drivers/perf: arm_spe: Fix consistency of SYS_PMSCR_EL1.CX

to the 5.10-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     drivers-perf-arm_spe-fix-consistency-of-sys_pmscr_el.patch
and it can be found in the queue-5.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 890e8d6b19c65efbbde8bd00af0ad245001a203f
Author: Anshuman Khandual <anshuman.khandual@xxxxxxx>
Date:   Thu Jul 14 11:43:02 2022 +0530

    drivers/perf: arm_spe: Fix consistency of SYS_PMSCR_EL1.CX
    
    [ Upstream commit 92f2b8bafa3d6e89c750e9d301a8b7ab76aaa8b6 ]
    
    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.
    
    Drop BIT(SYS_PMSCR_EL1_CX_SHIFT) check in arm_spe_pmu_event_init(), because
    now CX bit cannot be set in arm_spe_event_to_pmscr() with perfmon_capable()
    disabled.
    
    Cc: Will Deacon <will@xxxxxxxxxx>
    Cc: Mark Rutland <mark.rutland@xxxxxxx>
    Cc: Alexey Budankov <alexey.budankov@xxxxxxxxxxxxxxx>
    Cc: linux-arm-kernel@xxxxxxxxxxxxxxxxxxx
    Cc: linux-kernel@xxxxxxxxxxxxxxx
    Fixes: d5d9696b0380 ("drivers/perf: Add support for ARMv8.2 Statistical Profiling Extension")
    Reported-by: German Gomez <german.gomez@xxxxxxx>
    Signed-off-by: Anshuman Khandual <anshuman.khandual@xxxxxxx>
    Reviewed-by: Suzuki K Poulose <suzuki.poulose@xxxxxxx>
    Link: https://lore.kernel.org/r/20220714061302.2715102-1-anshuman.khandual@xxxxxxx
    Signed-off-by: Will Deacon <will@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c
index cc00915ad6d1..6fbfcab4918c 100644
--- a/drivers/perf/arm_spe_pmu.c
+++ b/drivers/perf/arm_spe_pmu.c
@@ -39,6 +39,24 @@
 #include <asm/mmu.h>
 #include <asm/sysreg.h>
 
+/*
+ * Cache if the event is allowed to trace Context information.
+ * This allows us to perform the check, i.e, perfmon_capable(),
+ * in the context of the event owner, once, during the event_init().
+ */
+#define SPE_PMU_HW_FLAGS_CX			BIT(0)
+
+static void set_spe_event_has_cx(struct perf_event *event)
+{
+	if (IS_ENABLED(CONFIG_PID_IN_CONTEXTIDR) && perfmon_capable())
+		event->hw.flags |= SPE_PMU_HW_FLAGS_CX;
+}
+
+static bool get_spe_event_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 {
@@ -274,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 (get_spe_event_has_cx(event))
 		reg |= BIT(SYS_PMSCR_EL1_CX_SHIFT);
 
 	return reg;
@@ -699,10 +717,10 @@ static int arm_spe_pmu_event_init(struct perf_event *event)
 	    !(spe_pmu->features & SPE_PMU_FEAT_FILT_LAT))
 		return -EOPNOTSUPP;
 
+	set_spe_event_has_cx(event);
 	reg = arm_spe_event_to_pmscr(event);
 	if (!perfmon_capable() &&
 	    (reg & (BIT(SYS_PMSCR_EL1_PA_SHIFT) |
-		    BIT(SYS_PMSCR_EL1_CX_SHIFT) |
 		    BIT(SYS_PMSCR_EL1_PCT_SHIFT))))
 		return -EACCES;
 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux