提交 02db49aa 编写于 作者: Y Yang Yingliang 提交者: Xie XiuQi

arm64: vdso: do cntvct workaround in the VDSO

hulk inclusion
category: performance
bugzilla: 16082
CVE: NA

-------------------------------------------------

If a cntvct workaround is enabled, read CNTVCT_EL0 twice
in VDSO to avoid the clock bug.

Test code:

static unsigned long long getcycle(void)
{
    unsigned long long cval;
    asm volatile("isb" : : : "memory");
    asm volatile("mrs %0, cntvct_el0" : "=r" (cval));
}

int main(void)
{
    int i;
    struct  timeval tv;
    struct  timezone tz;
    unsigned long long s = getcycle();

    for (i = 0; i < 100000000; i++) {
            gettimeofday(&tv,&tz);
    }
    printf("cost:%lld\n", getcycle() - s);

    return 0;
}

Before this patchset, it costs 75.78s:
[root@localhost yang]# ./gettime
cost:3789000522 (20ns per cycle)

After this patchset, it costs 3.58s:
[root@localhost yang]# ./gettime
cost:183208254 (20ns per cycle)
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
Reviewed-by: NXuefeng Wang <wxf.wang@hisilicon.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 bb6a8bef
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <linux/hrtimer.h> #include <linux/hrtimer.h>
extern struct vdso_data _vdso_data; extern struct vdso_data _vdso_data;
DECLARE_STATIC_KEY_FALSE(vdso_fix);
static notrace int gettimeofday_fallback(struct timeval *_tv, static notrace int gettimeofday_fallback(struct timeval *_tv,
struct timezone *_tz) struct timezone *_tz)
...@@ -119,6 +120,17 @@ static notrace u64 get_clock_shifted_nsec(u64 cycle_last, u64 mult) ...@@ -119,6 +120,17 @@ static notrace u64 get_clock_shifted_nsec(u64 cycle_last, u64 mult)
/* Read the virtual counter. */ /* Read the virtual counter. */
isb(); isb();
asm volatile("mrs %0, cntvct_el0" : "=r" (res) :: "memory"); asm volatile("mrs %0, cntvct_el0" : "=r" (res) :: "memory");
if (static_branch_unlikely(&vdso_fix)) {
u64 new;
int retries = 50;
asm volatile("mrs %0, cntvct_el0" : "=r" (new) :: "memory");
while (unlikely((new - res) >> 5) && retries) {
asm volatile("mrs %0, cntvct_el0" : "=r" (res) :: "memory");
asm volatile("mrs %0, cntvct_el0" : "=r" (new) :: "memory");
retries--;
}
}
res = res - cycle_last; res = res - cycle_last;
/* We can only guarantee 56 bits of precision. */ /* We can only guarantee 56 bits of precision. */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册