Messages in this thread Patch in this message | | | Date | Thu, 26 Oct 2023 11:06:38 +0100 | From | Marc Zyngier <> | Subject | Re: [PATCH] arm64: perf: Don't disgard upper 32 bits from PMCEID0/1 registers |
| |
On Wed, 25 Oct 2023 21:08:15 +0100, Ilkka Koskinen <ilkka@os.amperecomputing.com> wrote: > > The upper 32 bits of PMCEID[n] registers are used to describe whether > architectural and microarchitectural events in range 0x4000-0x401f > exist. Due to disgarding the bits, the driver made the events invisible, > even if they existed. > > Fixes: df29ddf4f04b ("arm64: perf: Abstract system register accesses away") > Reported-by: Carl Worth <carl@os.amperecomputing.com> > Signed-off-by: Ilkka Koskinen <ilkka@os.amperecomputing.com> > --- > arch/arm64/include/asm/arm_pmuv3.h | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/arch/arm64/include/asm/arm_pmuv3.h b/arch/arm64/include/asm/arm_pmuv3.h > index 18dc2fb3d7b7..3e92b7cb57a4 100644 > --- a/arch/arm64/include/asm/arm_pmuv3.h > +++ b/arch/arm64/include/asm/arm_pmuv3.h > @@ -126,12 +126,12 @@ static inline void write_pmuserenr(u32 val) > write_sysreg(val, pmuserenr_el0); > } > > -static inline u32 read_pmceid0(void) > +static inline u64 read_pmceid0(void) > { > return read_sysreg(pmceid0_el0); > } > > -static inline u32 read_pmceid1(void) > +static inline u64 read_pmceid1(void) > { > return read_sysreg(pmceid1_el0); > }
This is necessary, but not sufficient. You also need to update the corresponding 32bit accessors to match this behaviour. Something along the lines of the patch below
M.
diff --git a/arch/arm/include/asm/arm_pmuv3.h b/arch/arm/include/asm/arm_pmuv3.h index 72529f5e2bed..90841cb7ce43 100644 --- a/arch/arm/include/asm/arm_pmuv3.h +++ b/arch/arm/include/asm/arm_pmuv3.h @@ -23,6 +23,8 @@ #define PMUSERENR __ACCESS_CP15(c9, 0, c14, 0) #define PMINTENSET __ACCESS_CP15(c9, 0, c14, 1) #define PMINTENCLR __ACCESS_CP15(c9, 0, c14, 2) +#define PMCEID2 __ACCESS_CP15(c9, 0, c14, 4) +#define PMCEID3 __ACCESS_CP15(c9, 0, c14, 5) #define PMMIR __ACCESS_CP15(c9, 0, c14, 6) #define PMCCFILTR __ACCESS_CP15(c14, 0, c15, 7) @@ -205,16 +207,6 @@ static inline void write_pmuserenr(u32 val) write_sysreg(val, PMUSERENR); } -static inline u32 read_pmceid0(void) -{ - return read_sysreg(PMCEID0); -} - -static inline u32 read_pmceid1(void) -{ - return read_sysreg(PMCEID1); -} - static inline void kvm_set_pmu_events(u32 set, struct perf_event_attr *attr) {} static inline void kvm_clr_pmu_events(u32 clr) {} static inline bool kvm_pmu_counter_deferred(struct perf_event_attr *attr) @@ -231,6 +223,7 @@ static inline void kvm_vcpu_pmu_resync_el0(void) {} /* PMU Version in DFR Register */ #define ARMV8_PMU_DFR_VER_NI 0 +#define ARMV8_PMU_DFR_VER_V3P1 0x4 #define ARMV8_PMU_DFR_VER_V3P4 0x5 #define ARMV8_PMU_DFR_VER_V3P5 0x6 #define ARMV8_PMU_DFR_VER_IMP_DEF 0xF @@ -251,4 +244,24 @@ static inline bool is_pmuv3p5(int pmuver) return pmuver >= ARMV8_PMU_DFR_VER_V3P5; } +static inline u64 read_pmceid0(void) +{ + u64 val = read_sysreg(PMCEID0); + + if (read_pmuver() >= ARMV8_PMU_DFR_VER_V3P1) + val |= (u64)read_sysreg(PMCEID2) << 32; + + return val; +} + +static inline u64 read_pmceid1(void) +{ + u64 val = read_sysreg(PMCEID1); + + if (read_pmuver() >= ARMV8_PMU_DFR_VER_V3P1) + val |= (u64)read_sysreg(PMCEID3) << 32; + + return val; +} + #endif -- Without deviation from the norm, progress is not possible.
| |