Re: ERRATUM_858921 is broken on 5.15 kernel

From: Yogesh Lal
Date: Thu Jan 12 2023 - 07:49:14 EST



On 1/9/2023 4:09 PM, Marc Zyngier wrote:
On Mon, 09 Jan 2023 06:52:20 +0000,
Yogesh Lal <quic_ylal@xxxxxxxxxxx> wrote:
tested it on affected h/w but looks like sched_clock is still pointing
to !arch_timer_counter_has_wa() function calls,
may be due to sched_clock_register will register once during non
errata impacted core booting.
Ah, of course. We register the function itself instead of an
indirection. Please try this on top of the previous patch.
Thanks for the patch, its working fine now.

Thanks,

M.

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index a7cf0a2c86d3..8232c86b9e7c 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -217,7 +217,12 @@ static notrace u64 arch_counter_get_cntvct(void)
* to exist on arm64. arm doesn't use this before DT is probed so even
* if we don't have the cp15 accessors we won't have a problem.
*/
-u64 (*arch_timer_read_counter)(void) __ro_after_init = arch_counter_get_cntvct;
+static u64 (*__arch_timer_read_counter)(void) __ro_after_init = arch_counter_get_cntvct;
+
+u64 arch_timer_read_counter(void)
+{
+ return __arch_timer_read_counter();
+}
EXPORT_SYMBOL_GPL(arch_timer_read_counter);
static u64 arch_counter_read(struct clocksource *cs)
@@ -595,7 +600,7 @@ void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa
if (wa->read_cntvct_el0 || wa->read_cntpct_el0) {
atomic_set(&timer_unstable_counter_workaround_in_use, 1);
- arch_timer_read_counter = arch_counter_get_read_fn();
+ __arch_timer_read_counter = arch_counter_get_read_fn();
}
/*
@@ -1103,10 +1108,10 @@ static void __init arch_counter_register(unsigned type)
/* Register the CP15 based counter if we have one */
if (type & ARCH_TIMER_TYPE_CP15) {
- arch_timer_read_counter = arch_counter_get_read_fn();
+ __arch_timer_read_counter = arch_counter_get_read_fn();
clocksource_counter.vdso_clock_mode = vdso_default;
} else {
- arch_timer_read_counter = arch_counter_get_cntvct_mem;
+ __arch_timer_read_counter = arch_counter_get_cntvct_mem;
}
width = arch_counter_get_width();
diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
index e3c3816d19ba..3ac297a756e8 100644
--- a/include/clocksource/arm_arch_timer.h
+++ b/include/clocksource/arm_arch_timer.h
@@ -89,7 +89,7 @@ struct arch_timer_mem {
#ifdef CONFIG_ARM_ARCH_TIMER
extern u32 arch_timer_get_rate(void);
-extern u64 (*arch_timer_read_counter)(void);
+extern u64 arch_timer_read_counter(void);
extern struct arch_timer_kvm_info *arch_timer_get_kvm_info(void);
extern bool arch_timer_evtstrm_available(void);