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>
This commit is contained in:
parent
fdf865988b
commit
9ee840a960
|
@ -64,14 +64,26 @@ DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *,
|
||||||
|
|
||||||
static inline notrace u64 arch_timer_read_cntpct_el0(void)
|
static inline notrace u64 arch_timer_read_cntpct_el0(void)
|
||||||
{
|
{
|
||||||
isb();
|
u64 cnt;
|
||||||
return read_sysreg(cntpct_el0);
|
|
||||||
|
asm volatile(ALTERNATIVE("isb\n mrs %0, cntpct_el0",
|
||||||
|
"nop\n" __mrs_s("%0", SYS_CNTPCTSS_EL0),
|
||||||
|
ARM64_HAS_ECV)
|
||||||
|
: "=r" (cnt));
|
||||||
|
|
||||||
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline notrace u64 arch_timer_read_cntvct_el0(void)
|
static inline notrace u64 arch_timer_read_cntvct_el0(void)
|
||||||
{
|
{
|
||||||
isb();
|
u64 cnt;
|
||||||
return read_sysreg(cntvct_el0);
|
|
||||||
|
asm volatile(ALTERNATIVE("isb\n mrs %0, cntvct_el0",
|
||||||
|
"nop\n" __mrs_s("%0", SYS_CNTVCTSS_EL0),
|
||||||
|
ARM64_HAS_ECV)
|
||||||
|
: "=r" (cnt));
|
||||||
|
|
||||||
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define arch_timer_reg_read_stable(reg) \
|
#define arch_timer_reg_read_stable(reg) \
|
||||||
|
@ -174,8 +186,10 @@ static __always_inline u64 __arch_counter_get_cntpct(void)
|
||||||
{
|
{
|
||||||
u64 cnt;
|
u64 cnt;
|
||||||
|
|
||||||
isb();
|
asm volatile(ALTERNATIVE("isb\n mrs %0, cntpct_el0",
|
||||||
cnt = read_sysreg(cntpct_el0);
|
"nop\n" __mrs_s("%0", SYS_CNTPCTSS_EL0),
|
||||||
|
ARM64_HAS_ECV)
|
||||||
|
: "=r" (cnt));
|
||||||
arch_counter_enforce_ordering(cnt);
|
arch_counter_enforce_ordering(cnt);
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
@ -193,8 +207,10 @@ static __always_inline u64 __arch_counter_get_cntvct(void)
|
||||||
{
|
{
|
||||||
u64 cnt;
|
u64 cnt;
|
||||||
|
|
||||||
isb();
|
asm volatile(ALTERNATIVE("isb\n mrs %0, cntvct_el0",
|
||||||
cnt = read_sysreg(cntvct_el0);
|
"nop\n" __mrs_s("%0", SYS_CNTVCTSS_EL0),
|
||||||
|
ARM64_HAS_ECV)
|
||||||
|
: "=r" (cnt));
|
||||||
arch_counter_enforce_ordering(cnt);
|
arch_counter_enforce_ordering(cnt);
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -507,6 +507,9 @@
|
||||||
|
|
||||||
#define SYS_CNTFRQ_EL0 sys_reg(3, 3, 14, 0, 0)
|
#define SYS_CNTFRQ_EL0 sys_reg(3, 3, 14, 0, 0)
|
||||||
|
|
||||||
|
#define SYS_CNTPCTSS_EL0 sys_reg(3, 3, 14, 0, 5)
|
||||||
|
#define SYS_CNTVCTSS_EL0 sys_reg(3, 3, 14, 0, 6)
|
||||||
|
|
||||||
#define SYS_CNTP_TVAL_EL0 sys_reg(3, 3, 14, 2, 0)
|
#define SYS_CNTP_TVAL_EL0 sys_reg(3, 3, 14, 2, 0)
|
||||||
#define SYS_CNTP_CTL_EL0 sys_reg(3, 3, 14, 2, 1)
|
#define SYS_CNTP_CTL_EL0 sys_reg(3, 3, 14, 2, 1)
|
||||||
#define SYS_CNTP_CVAL_EL0 sys_reg(3, 3, 14, 2, 2)
|
#define SYS_CNTP_CVAL_EL0 sys_reg(3, 3, 14, 2, 2)
|
||||||
|
|
Loading…
Reference in New Issue