Skip to content

Commit 9ee840a

Browse files
Marc Zyngierwilldeacon
authored andcommitted
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 <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent fdf8659 commit 9ee840a

File tree

2 files changed

+27
-8
lines changed

2 files changed

+27
-8
lines changed

arch/arm64/include/asm/arch_timer.h

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,26 @@ DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *,
6464

6565
static inline notrace u64 arch_timer_read_cntpct_el0(void)
6666
{
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;
6975
}
7076

7177
static inline notrace u64 arch_timer_read_cntvct_el0(void)
7278
{
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;
7587
}
7688

7789
#define arch_timer_reg_read_stable(reg) \
@@ -174,8 +186,10 @@ static __always_inline u64 __arch_counter_get_cntpct(void)
174186
{
175187
u64 cnt;
176188

177-
isb();
178-
cnt = read_sysreg(cntpct_el0);
189+
asm volatile(ALTERNATIVE("isb\n mrs %0, cntpct_el0",
190+
"nop\n" __mrs_s("%0", SYS_CNTPCTSS_EL0),
191+
ARM64_HAS_ECV)
192+
: "=r" (cnt));
179193
arch_counter_enforce_ordering(cnt);
180194
return cnt;
181195
}
@@ -193,8 +207,10 @@ static __always_inline u64 __arch_counter_get_cntvct(void)
193207
{
194208
u64 cnt;
195209

196-
isb();
197-
cnt = read_sysreg(cntvct_el0);
210+
asm volatile(ALTERNATIVE("isb\n mrs %0, cntvct_el0",
211+
"nop\n" __mrs_s("%0", SYS_CNTVCTSS_EL0),
212+
ARM64_HAS_ECV)
213+
: "=r" (cnt));
198214
arch_counter_enforce_ordering(cnt);
199215
return cnt;
200216
}

arch/arm64/include/asm/sysreg.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,9 @@
507507

508508
#define SYS_CNTFRQ_EL0 sys_reg(3, 3, 14, 0, 0)
509509

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+
510513
#define SYS_CNTP_TVAL_EL0 sys_reg(3, 3, 14, 2, 0)
511514
#define SYS_CNTP_CTL_EL0 sys_reg(3, 3, 14, 2, 1)
512515
#define SYS_CNTP_CVAL_EL0 sys_reg(3, 3, 14, 2, 2)

0 commit comments

Comments
 (0)