Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arm64: Add CNT{P,V}CTSS_EL0 alternatives to cnt{p,v}ct_el0

CNTPCTSS_EL0 and CNTVCTSS_EL0 are alternatives to the usual
CNTPCT_EL0 and CNTVCT_EL0 that do not require a previous ISB
to be synchronised (SS stands for Self-Synchronising).

Use the ARM64_HAS_ECV capability to control alternative sequences
that switch to these low(er)-cost primitives. Note that the
counter access in the VDSO is for now left alone until we decide
whether we want to allow this.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20211017124225.3018098-16-maz@kernel.org
Signed-off-by: Will Deacon <will@kernel.org>

authored by

Marc Zyngier and committed by
Will Deacon
9ee840a9 fdf86598

+27 -8
+24 -8
arch/arm64/include/asm/arch_timer.h
··· 64 64 65 65 static inline notrace u64 arch_timer_read_cntpct_el0(void) 66 66 { 67 - isb(); 68 - return read_sysreg(cntpct_el0); 67 + u64 cnt; 68 + 69 + asm volatile(ALTERNATIVE("isb\n mrs %0, cntpct_el0", 70 + "nop\n" __mrs_s("%0", SYS_CNTPCTSS_EL0), 71 + ARM64_HAS_ECV) 72 + : "=r" (cnt)); 73 + 74 + return cnt; 69 75 } 70 76 71 77 static inline notrace u64 arch_timer_read_cntvct_el0(void) 72 78 { 73 - isb(); 74 - return read_sysreg(cntvct_el0); 79 + u64 cnt; 80 + 81 + asm volatile(ALTERNATIVE("isb\n mrs %0, cntvct_el0", 82 + "nop\n" __mrs_s("%0", SYS_CNTVCTSS_EL0), 83 + ARM64_HAS_ECV) 84 + : "=r" (cnt)); 85 + 86 + return cnt; 75 87 } 76 88 77 89 #define arch_timer_reg_read_stable(reg) \ ··· 186 174 { 187 175 u64 cnt; 188 176 189 - isb(); 190 - cnt = read_sysreg(cntpct_el0); 177 + asm volatile(ALTERNATIVE("isb\n mrs %0, cntpct_el0", 178 + "nop\n" __mrs_s("%0", SYS_CNTPCTSS_EL0), 179 + ARM64_HAS_ECV) 180 + : "=r" (cnt)); 191 181 arch_counter_enforce_ordering(cnt); 192 182 return cnt; 193 183 } ··· 207 193 { 208 194 u64 cnt; 209 195 210 - isb(); 211 - cnt = read_sysreg(cntvct_el0); 196 + asm volatile(ALTERNATIVE("isb\n mrs %0, cntvct_el0", 197 + "nop\n" __mrs_s("%0", SYS_CNTVCTSS_EL0), 198 + ARM64_HAS_ECV) 199 + : "=r" (cnt)); 212 200 arch_counter_enforce_ordering(cnt); 213 201 return cnt; 214 202 }
+3
arch/arm64/include/asm/sysreg.h
··· 507 507 508 508 #define SYS_CNTFRQ_EL0 sys_reg(3, 3, 14, 0, 0) 509 509 510 + #define SYS_CNTPCTSS_EL0 sys_reg(3, 3, 14, 0, 5) 511 + #define SYS_CNTVCTSS_EL0 sys_reg(3, 3, 14, 0, 6) 512 + 510 513 #define SYS_CNTP_TVAL_EL0 sys_reg(3, 3, 14, 2, 0) 511 514 #define SYS_CNTP_CTL_EL0 sys_reg(3, 3, 14, 2, 1) 512 515 #define SYS_CNTP_CVAL_EL0 sys_reg(3, 3, 14, 2, 2)