提交 609a81be 编写于 作者: Y Yang Yingliang 提交者: Zheng Zengkai

arm64: arch_timer: Disable CNTVCT_EL0 trap if workaround is enabled

hulk inclusion
category: feature
bugzilla: 47984
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, introduce vdso_fix and vdso_shift for doing cntvct
workaround in VDSO.
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
Reviewed-by: NHanjun Guo <guohanjun@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 546c5fc5
...@@ -74,6 +74,8 @@ static enum vdso_clock_mode vdso_default = VDSO_CLOCKMODE_ARCHTIMER; ...@@ -74,6 +74,8 @@ static enum vdso_clock_mode vdso_default = VDSO_CLOCKMODE_ARCHTIMER;
#else #else
static enum vdso_clock_mode vdso_default = VDSO_CLOCKMODE_NONE; static enum vdso_clock_mode vdso_default = VDSO_CLOCKMODE_NONE;
#endif /* CONFIG_GENERIC_GETTIMEOFDAY */ #endif /* CONFIG_GENERIC_GETTIMEOFDAY */
static bool vdso_fix;
static u16 vdso_shift;
static cpumask_t evtstrm_available = CPU_MASK_NONE; static cpumask_t evtstrm_available = CPU_MASK_NONE;
static bool evtstrm_enable = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM); static bool evtstrm_enable = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM);
...@@ -572,8 +574,17 @@ void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa ...@@ -572,8 +574,17 @@ void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa
* change both the default value and the vdso itself. * change both the default value and the vdso itself.
*/ */
if (wa->read_cntvct_el0) { if (wa->read_cntvct_el0) {
clocksource_counter.vdso_clock_mode = VDSO_CLOCKMODE_NONE; if (!strncmp(wa->desc, "HiSilicon erratum 161010101",
vdso_default = VDSO_CLOCKMODE_NONE; strlen("HiSilicon erratum 161010101"))) {
vdso_fix = true;
vdso_shift = 5;
} else if (!strncmp(wa->desc, "Freescale erratum a005858",
strlen("Freescale erratum a005858"))) {
vdso_fix = true;
} else {
clocksource_counter.vdso_clock_mode = VDSO_CLOCKMODE_NONE;
vdso_default = VDSO_CLOCKMODE_NONE;
}
} else if (wa->disable_compat_vdso && vdso_default != VDSO_CLOCKMODE_NONE) { } else if (wa->disable_compat_vdso && vdso_default != VDSO_CLOCKMODE_NONE) {
vdso_default = VDSO_CLOCKMODE_ARCHTIMER_NOCOMPAT; vdso_default = VDSO_CLOCKMODE_ARCHTIMER_NOCOMPAT;
clocksource_counter.vdso_clock_mode = vdso_default; clocksource_counter.vdso_clock_mode = vdso_default;
...@@ -859,7 +870,7 @@ static void arch_counter_set_user_access(void) ...@@ -859,7 +870,7 @@ static void arch_counter_set_user_access(void)
* need to be workaround. The vdso may have been already * need to be workaround. The vdso may have been already
* disabled though. * 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()); pr_info("CPU%d: Trapping CNTVCT access\n", smp_processor_id());
else else
cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN; cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN;
...@@ -1015,6 +1026,8 @@ static void __init arch_counter_register(unsigned type) ...@@ -1015,6 +1026,8 @@ static void __init arch_counter_register(unsigned type)
arch_timer_read_counter = rd; arch_timer_read_counter = rd;
clocksource_counter.vdso_clock_mode = vdso_default; clocksource_counter.vdso_clock_mode = vdso_default;
clocksource_counter.vdso_fix = vdso_fix;
clocksource_counter.vdso_shift = vdso_shift;
} else { } else {
arch_timer_read_counter = arch_counter_get_cntvct_mem; arch_timer_read_counter = arch_counter_get_cntvct_mem;
} }
......
...@@ -101,6 +101,8 @@ struct clocksource { ...@@ -101,6 +101,8 @@ struct clocksource {
struct list_head list; struct list_head list;
int rating; int rating;
enum vdso_clock_mode vdso_clock_mode; enum vdso_clock_mode vdso_clock_mode;
u16 vdso_fix;
u16 vdso_shift;
unsigned long flags; unsigned long flags;
int (*enable)(struct clocksource *cs); int (*enable)(struct clocksource *cs);
......
...@@ -69,7 +69,8 @@ struct vdso_timestamp { ...@@ -69,7 +69,8 @@ struct vdso_timestamp {
* @tz_minuteswest: minutes west of Greenwich * @tz_minuteswest: minutes west of Greenwich
* @tz_dsttime: type of DST correction * @tz_dsttime: type of DST correction
* @hrtimer_res: hrtimer resolution * @hrtimer_res: hrtimer resolution
* @__unused: unused * @vdso_fix: avoid the clock bug in VDSO
* @vdso_shift: count of bit to be ignored
* @arch_data: architecture specific data (optional, defaults * @arch_data: architecture specific data (optional, defaults
* to an empty struct) * to an empty struct)
* *
...@@ -104,7 +105,8 @@ struct vdso_data { ...@@ -104,7 +105,8 @@ struct vdso_data {
s32 tz_minuteswest; s32 tz_minuteswest;
s32 tz_dsttime; s32 tz_dsttime;
u32 hrtimer_res; u32 hrtimer_res;
u32 __unused; u16 vdso_fix;
u16 vdso_shift;
struct arch_vdso_data arch_data; struct arch_vdso_data arch_data;
}; };
......
...@@ -74,14 +74,22 @@ void update_vsyscall(struct timekeeper *tk) ...@@ -74,14 +74,22 @@ void update_vsyscall(struct timekeeper *tk)
struct vdso_data *vdata = __arch_get_k_vdso_data(); struct vdso_data *vdata = __arch_get_k_vdso_data();
struct vdso_timestamp *vdso_ts; struct vdso_timestamp *vdso_ts;
s32 clock_mode; s32 clock_mode;
u16 vdso_fix;
u16 vdso_shift;
u64 nsec; u64 nsec;
/* copy vsyscall data */ /* copy vsyscall data */
vdso_write_begin(vdata); vdso_write_begin(vdata);
clock_mode = tk->tkr_mono.clock->vdso_clock_mode; clock_mode = tk->tkr_mono.clock->vdso_clock_mode;
vdso_fix = tk->tkr_mono.clock->vdso_fix;
vdso_shift = tk->tkr_mono.clock->vdso_shift;
vdata[CS_HRES_COARSE].clock_mode = clock_mode; vdata[CS_HRES_COARSE].clock_mode = clock_mode;
vdata[CS_HRES_COARSE].vdso_fix = vdso_fix;
vdata[CS_HRES_COARSE].vdso_shift = vdso_shift;
vdata[CS_RAW].clock_mode = clock_mode; vdata[CS_RAW].clock_mode = clock_mode;
vdata[CS_RAW].vdso_fix = vdso_fix;
vdata[CS_RAW].vdso_shift = vdso_shift;
/* CLOCK_REALTIME also required for time() */ /* CLOCK_REALTIME also required for time() */
vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME]; vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME];
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册