From 60b42e93900179408302e480f148834f30fa2f34 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Wed, 22 May 2019 12:21:59 +0800 Subject: [PATCH] arm64: arch_timer: Disable CNTVCT_EL0 trap if workaround is enabled hulk inclusion category: performance bugzilla: 16082 CVE: NA ------------------------------------------------- It costs very much time to read CNTVCT_EL0, if a cntvct workaround and CNTVCT_EL0 trap is enabled. To decrease the read time, we disable CNTVCT_EL0 trap and do the cntvct workaround in the VDSO by adding vdso_fix. Signed-off-by: Yang Yingliang --- arch/arm64/include/asm/clocksource.h | 1 + arch/arm64/include/asm/vdso_datapage.h | 1 + arch/arm64/kernel/vdso.c | 1 + drivers/clocksource/arm_arch_timer.c | 10 +++++++--- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/arch/arm64/include/asm/clocksource.h b/arch/arm64/include/asm/clocksource.h index 0ece64a26c8c..734428342ebf 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 2b9a63771eda..4c4fc13bfea5 100644 --- a/arch/arm64/include/asm/vdso_datapage.h +++ b/arch/arm64/include/asm/vdso_datapage.h @@ -38,6 +38,7 @@ struct vdso_data { __u32 tz_minuteswest; /* Whacky timezone stuff */ __u32 tz_dsttime; __u32 use_syscall; + __u32 vdso_fix; /* Avoid the clock bug in VDSO */ }; #endif /* !__ASSEMBLY__ */ diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 9fb0c0c95a85..ade5ca532c28 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/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 0445ad7e559e..43fcd3facd99 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -76,6 +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; +static bool vdso_fix = false; static cpumask_t evtstrm_available = CPU_MASK_NONE; static bool evtstrm_enable = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM); @@ -550,8 +551,10 @@ void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa * change both the default value and the vdso itself. */ if (wa->read_cntvct_el0) { - clocksource_counter.archdata.vdso_direct = false; - vdso_default = false; + clocksource_counter.archdata.vdso_direct = true; + clocksource_counter.archdata.vdso_fix = true; + vdso_default = true; + vdso_fix = true; } } @@ -855,7 +858,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()) + 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; @@ -990,6 +993,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; } -- GitLab