Skip to content

Commit 9497f70

Browse files
Lorenzo Pieralisigregkh
authored andcommitted
arm64: kernel: fix architected PMU registers unconditional access
commit f436b2ac90a095746beb6729b8ee8ed87c9eaede upstream. The Performance Monitors extension is an optional feature of the AArch64 architecture, therefore, in order to access Performance Monitors registers safely, the kernel should detect the architected PMU unit presence through the ID_AA64DFR0_EL1 register PMUVer field before accessing them. This patch implements a guard by reading the ID_AA64DFR0_EL1 register PMUVer field to detect the architected PMU presence and prevent accessing PMU system registers if the Performance Monitors extension is not implemented in the core. Cc: Peter Maydell <peter.maydell@linaro.org> Cc: Mark Rutland <mark.rutland@arm.com> Fixes: 60792ad349f3 ("arm64: kernel: enforce pmuserenr_el0 initialization and restore") Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Reported-by: Guenter Roeck <linux@roeck-us.net> Tested-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent f50c290 commit 9497f70

3 files changed

Lines changed: 19 additions & 2 deletions

File tree

arch/arm64/kernel/head.S

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,9 +512,14 @@ CPU_LE( movk x0, #0x30d0, lsl #16 ) // Clear EE and E0E on LE systems
512512
#endif
513513

514514
/* EL2 debug */
515+
mrs x0, id_aa64dfr0_el1 // Check ID_AA64DFR0_EL1 PMUVer
516+
sbfx x0, x0, #8, #4
517+
cmp x0, #1
518+
b.lt 4f // Skip if no PMU present
515519
mrs x0, pmcr_el0 // Disable debug access traps
516520
ubfx x0, x0, #11, #5 // to EL2 and allow access to
517521
msr mdcr_el2, x0 // all PMU counters from EL1
522+
4:
518523

519524
/* Stage-2 translation */
520525
msr vttbr_el2, xzr

arch/arm64/mm/proc-macros.S

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,15 @@
6262
bfi \valreg, \tmpreg, #TCR_T0SZ_OFFSET, #TCR_TxSZ_WIDTH
6363
#endif
6464
.endm
65+
66+
/*
67+
* reset_pmuserenr_el0 - reset PMUSERENR_EL0 if PMUv3 present
68+
*/
69+
.macro reset_pmuserenr_el0, tmpreg
70+
mrs \tmpreg, id_aa64dfr0_el1 // Check ID_AA64DFR0_EL1 PMUVer
71+
sbfx \tmpreg, \tmpreg, #8, #4
72+
cmp \tmpreg, #1 // Skip if no PMU present
73+
b.lt 9000f
74+
msr pmuserenr_el0, xzr // Disable PMU access from EL0
75+
9000:
76+
.endm

arch/arm64/mm/proc.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ ENTRY(cpu_do_resume)
117117
*/
118118
ubfx x11, x11, #1, #1
119119
msr oslar_el1, x11
120-
msr pmuserenr_el0, xzr // Disable PMU access from EL0
120+
reset_pmuserenr_el0 x0 // Disable PMU access from EL0
121121
mov x0, x12
122122
dsb nsh // Make sure local tlb invalidation completed
123123
isb
@@ -156,7 +156,7 @@ ENTRY(__cpu_setup)
156156
msr cpacr_el1, x0 // Enable FP/ASIMD
157157
mov x0, #1 << 12 // Reset mdscr_el1 and disable
158158
msr mdscr_el1, x0 // access to the DCC from EL0
159-
msr pmuserenr_el0, xzr // Disable PMU access from EL0
159+
reset_pmuserenr_el0 x0 // Disable PMU access from EL0
160160
/*
161161
* Memory region attributes for LPAE:
162162
*

0 commit comments

Comments
 (0)