arm64: arm_pmuv3: Correctly extract and check the PMUVer
authorYicong Yang <yangyicong@hisilicon.com>
Thu, 11 Apr 2024 12:30:30 +0000 (20:30 +0800)
committerWill Deacon <will@kernel.org>
Fri, 12 Apr 2024 11:54:55 +0000 (12:54 +0100)
Currently we're using "sbfx" to extract the PMUVer from ID_AA64DFR0_EL1
and skip the init/reset if no PMU present when the extracted PMUVer is
negative or is zero. However for PMUv3p8 the PMUVer will be 0b1000 and
PMUVer extracted by "sbfx" will always be negative and we'll skip the
init/reset in __init_el2_debug/reset_pmuserenr_el0 unexpectedly.

So this patch use "ubfx" instead of "sbfx" to extract the PMUVer. If
the PMUVer is implementation defined (0b1111) or not implemented(0b0000)
then skip the reset/init. Previously we'll also skip the init/reset
if the PMUVer is higher than the version we known (currently PMUv3p9),
with this patch we'll only skip if the PMU is not implemented or
implementation defined. This keeps consistence with how we probe
the PMU in the driver with pmuv3_implemented().

Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
Link: https://lore.kernel.org/r/20240411123030.7201-1-yangyicong@huawei.com
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/include/asm/assembler.h
arch/arm64/include/asm/el2_setup.h

index ab8b396428da8ab920d4fd5cee7760b41c04a6b2..9ecd076ba08fc605d2b10d7698ee6f71d656b471 100644 (file)
@@ -480,9 +480,10 @@ alternative_endif
  */
        .macro  reset_pmuserenr_el0, tmpreg
        mrs     \tmpreg, id_aa64dfr0_el1
-       sbfx    \tmpreg, \tmpreg, #ID_AA64DFR0_EL1_PMUVer_SHIFT, #4
-       cmp     \tmpreg, #1                     // Skip if no PMU present
-       b.lt    9000f
+       ubfx    \tmpreg, \tmpreg, #ID_AA64DFR0_EL1_PMUVer_SHIFT, #4
+       cmp     \tmpreg, #ID_AA64DFR0_EL1_PMUVer_NI
+       ccmp    \tmpreg, #ID_AA64DFR0_EL1_PMUVer_IMP_DEF, #4, ne
+       b.eq    9000f                           // Skip if no PMU present or IMP_DEF
        msr     pmuserenr_el0, xzr              // Disable PMU access from EL0
 9000:
        .endm
index b7afaa026842b7ebce94228e6031ce99f5cbb2a8..e4546b29dd0cbfbb5b902e15caadab69458b1fac 100644 (file)
 
 .macro __init_el2_debug
        mrs     x1, id_aa64dfr0_el1
-       sbfx    x0, x1, #ID_AA64DFR0_EL1_PMUVer_SHIFT, #4
-       cmp     x0, #1
-       b.lt    .Lskip_pmu_\@                   // Skip if no PMU present
+       ubfx    x0, x1, #ID_AA64DFR0_EL1_PMUVer_SHIFT, #4
+       cmp     x0, #ID_AA64DFR0_EL1_PMUVer_NI
+       ccmp    x0, #ID_AA64DFR0_EL1_PMUVer_IMP_DEF, #4, ne
+       b.eq    .Lskip_pmu_\@                   // Skip if no PMU present or IMP_DEF
        mrs     x0, pmcr_el0                    // Disable debug access traps
        ubfx    x0, x0, #11, #5                 // to EL2 and allow access to
 .Lskip_pmu_\@:
-       csel    x2, xzr, x0, lt                 // all PMU counters from EL1
+       csel    x2, xzr, x0, eq                 // all PMU counters from EL1
 
        /* Statistical profiling */
        ubfx    x0, x1, #ID_AA64DFR0_EL1_PMSVer_SHIFT, #4