diff --git a/arch/arm64/include/asm/clocksource.h b/arch/arm64/include/asm/clocksource.h index 0ece64a26c8c94d04c7aac8a35b7bc8dd0000b85..734428342ebfe76a913993969546acf89adfe8d9 100644 --- a/arch/arm64/include/asm/clocksource.h +++ b/arch/arm64/include/asm/clocksource.h @@ -4,6 +4,7 @@ struct arch_clocksource_data { bool vdso_direct; /* Usable for direct VDSO access? */ + bool vdso_fix; /* Need avoid the clock bug in VDSO? */ }; #endif diff --git a/arch/arm64/include/asm/vdso_datapage.h b/arch/arm64/include/asm/vdso_datapage.h index f89263c8e11affe95f628b848dd344a766860b9c..6c466a041d75781ac9d483faa6037cfe3cfeca99 100644 --- a/arch/arm64/include/asm/vdso_datapage.h +++ b/arch/arm64/include/asm/vdso_datapage.h @@ -39,6 +39,7 @@ struct vdso_data { __u32 tz_dsttime; __u32 use_syscall; __u32 hrtimer_res; + __u32 vdso_fix; /* Avoid the clock bug in VDSO */ }; #endif /* !__ASSEMBLY__ */ diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c index 7106417842d65e0a6de567a9a74fdd569521de4a..5ee9f3985977a02abd88a94329cbdead44561a30 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c @@ -122,6 +122,7 @@ int main(void) DEFINE(VDSO_TZ_MINWEST, offsetof(struct vdso_data, tz_minuteswest)); DEFINE(VDSO_TZ_DSTTIME, offsetof(struct vdso_data, tz_dsttime)); DEFINE(VDSO_USE_SYSCALL, offsetof(struct vdso_data, use_syscall)); + DEFINE(VDSO_FIX, offsetof(struct vdso_data, vdso_fix)); BLANK(); DEFINE(TVAL_TV_SEC, offsetof(struct timeval, tv_sec)); DEFINE(TVAL_TV_USEC, offsetof(struct timeval, tv_usec)); diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 42b7082029e1d5003e509ffdbf4d916cbeb43dc7..fc72138b5c2572a945b6e757acdca93376f4fc72 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -224,6 +224,7 @@ void update_vsyscall(struct timekeeper *tk) smp_wmb(); vdso_data->use_syscall = use_syscall; + vdso_data->vdso_fix = tk->tkr_mono.clock->archdata.vdso_fix; vdso_data->xtime_coarse_sec = tk->xtime_sec; vdso_data->xtime_coarse_nsec = tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift; diff --git a/arch/arm64/kernel/vdso/gettimeofday.c b/arch/arm64/kernel/vdso/gettimeofday.c index 382c76d3109bbf1eb265bb6bbce9c7196bb3acff..2e28ff5bb1e2f837974cb1dc24b138f22ae18148 100644 --- a/arch/arm64/kernel/vdso/gettimeofday.c +++ b/arch/arm64/kernel/vdso/gettimeofday.c @@ -29,7 +29,6 @@ #include extern struct vdso_data _vdso_data; -DECLARE_STATIC_KEY_FALSE(vdso_fix); static notrace int gettimeofday_fallback(struct timeval *_tv, struct timezone *_tz) @@ -120,7 +119,7 @@ static notrace u64 get_clock_shifted_nsec(u64 cycle_last, u64 mult) /* Read the virtual counter. */ isb(); asm volatile("mrs %0, cntvct_el0" : "=r" (res) :: "memory"); - if (static_branch_unlikely(&vdso_fix)) { + if (_vdso_data.vdso_fix) { u64 new; int retries = 50; diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index eeea2bd27c1ec91790ce44c000fc56aaf54fecf6..486e51605e6836740eb1427a0cdf831190fd96ab 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -76,7 +76,7 @@ static bool arch_timer_c3stop; static bool arch_timer_mem_use_virtual; static bool arch_counter_suspend_stop; static bool vdso_default = true; -DEFINE_STATIC_KEY_FALSE(vdso_fix); +static bool vdso_fix; static cpumask_t evtstrm_available = CPU_MASK_NONE; static bool evtstrm_enable = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM); @@ -553,7 +553,7 @@ void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa if (wa->read_cntvct_el0) { clocksource_counter.archdata.vdso_direct = true; vdso_default = true; - static_branch_enable(&vdso_fix); + vdso_fix = true; } } @@ -857,8 +857,7 @@ static void arch_counter_set_user_access(void) * need to be workaround. The vdso may have been already * disabled though. */ - if (arch_timer_this_cpu_has_cntvct_wa() && - !static_branch_unlikely(&vdso_fix)) + if (arch_timer_this_cpu_has_cntvct_wa() && !vdso_fix) pr_info("CPU%d: Trapping CNTVCT access\n", smp_processor_id()); else cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN; @@ -993,6 +992,7 @@ static void __init arch_counter_register(unsigned type) arch_timer_read_counter = arch_counter_get_cntpct; clocksource_counter.archdata.vdso_direct = vdso_default; + clocksource_counter.archdata.vdso_fix = vdso_fix; } else { arch_timer_read_counter = arch_counter_get_cntvct_mem; }