From: Mark Salyzyn Date: Fri, 27 Oct 2017 15:58:18 +0000 (-0700) Subject: FROMLIST: lib: vdso: add support for time X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=fb595479b72e28511f80ef95eda9d915b06642c9;p=GitHub%2Fexynos8895%2Fandroid_kernel_samsung_universal8895.git FROMLIST: lib: vdso: add support for time (cherry pick from url https://patchwork.kernel.org/patch/10053549/) Add time() vdso support to match up with existing support in the x86's vdso. Currently benefitting arm and arm64 which uses the common vgettimeofday.c implementation. On arm provides about a ~14 fold improvement in speed over the straight syscall, and about a ~5 fold improvement in speed over an alternate library implementation that relies on the vdso call to gettimeofday to fulfill the request. We can provide __vdso_time even if we can not provide a speed enhanced __vdso_gettimeofday. Signed-off-by: Mark Salyzyn Bug: 63737556 Bug: 20045882 Change-Id: I0bb3c6bafe57f9ed69350e2dd54edaae58316e8f --- diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c index e50a72ca08f1..bb241d4afea7 100644 --- a/arch/arm/kernel/vdso.c +++ b/arch/arm/kernel/vdso.c @@ -172,6 +172,7 @@ static void __init patch_vdso(void *ehdr) vdso_nullpatch_one(&einfo, "__vdso_gettimeofday"); vdso_nullpatch_one(&einfo, "__vdso_clock_gettime"); vdso_nullpatch_one(&einfo, "__vdso_clock_getres"); + /* do not zero out __vdso_time, no cntvct_ok dependency */ } } diff --git a/arch/arm/vdso/vdso.lds.S b/arch/arm/vdso/vdso.lds.S index 1d81e8c3acf6..1eb577091d1f 100644 --- a/arch/arm/vdso/vdso.lds.S +++ b/arch/arm/vdso/vdso.lds.S @@ -83,6 +83,7 @@ VERSION __vdso_clock_gettime; __vdso_gettimeofday; __vdso_clock_getres; + __vdso_time; local: *; }; } diff --git a/arch/arm64/kernel/vdso/compiler.h b/arch/arm64/kernel/vdso/compiler.h new file mode 100644 index 000000000000..fb27545640f2 --- /dev/null +++ b/arch/arm64/kernel/vdso/compiler.h @@ -0,0 +1,70 @@ +/* + * Userspace implementations of fallback calls + * + * Copyright (C) 2017 Cavium, Inc. + * Copyright (C) 2012 ARM Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Author: Will Deacon + * Rewriten into C by: Andrew Pinski + */ + +#ifndef __VDSO_COMPILER_H +#define __VDSO_COMPILER_H + +#include /* for cpu_relax() */ +#include /* for read_sysreg() */ +#include +#include +#include /* for LOW_RES_NSEC and MONOTONIC_RES_NSEC */ + +#ifdef CONFIG_ARM_ARCH_TIMER +#define ARCH_PROVIDES_TIMER +#endif + +#define DEFINE_FALLBACK(name, type_arg1, name_arg1, type_arg2, name_arg2) \ +static notrace long name##_fallback(type_arg1 _##name_arg1, \ + type_arg2 _##name_arg2) \ +{ \ + register type_arg1 name_arg1 asm("x0") = _##name_arg1; \ + register type_arg2 name_arg2 asm("x1") = _##name_arg2; \ + register long ret asm ("x0"); \ + register long nr asm("x8") = __NR_##name; \ + \ + asm volatile( \ + " svc #0\n" \ + : "=r" (ret) \ + : "r" (name_arg1), "r" (name_arg2), "r" (nr) \ + : "memory"); \ + \ + return ret; \ +} + +/* + * AArch64 implementation of arch_counter_get_cntvct() suitable for vdso + */ +static __always_inline notrace u64 arch_vdso_read_counter(void) +{ + /* Read the virtual counter. */ + isb(); + return read_sysreg(cntvct_el0); +} + +/* Rename exported vdso functions */ +#define __vdso_clock_gettime __kernel_clock_gettime +#define __vdso_gettimeofday __kernel_gettimeofday +#define __vdso_clock_getres __kernel_clock_getres +#define __vdso_time __kernel_time + +#endif /* __VDSO_COMPILER_H */ diff --git a/arch/arm64/kernel/vdso/vdso.lds.S b/arch/arm64/kernel/vdso/vdso.lds.S index beca249bc2f3..9de0ffc369c5 100644 --- a/arch/arm64/kernel/vdso/vdso.lds.S +++ b/arch/arm64/kernel/vdso/vdso.lds.S @@ -88,6 +88,7 @@ VERSION __kernel_gettimeofday; __kernel_clock_gettime; __kernel_clock_getres; + __kernel_time; local: *; }; } diff --git a/lib/vdso/vgettimeofday.c b/lib/vdso/vgettimeofday.c index 075a1171944d..00d93df8045f 100644 --- a/lib/vdso/vgettimeofday.c +++ b/lib/vdso/vgettimeofday.c @@ -385,3 +385,13 @@ int __vdso_clock_getres(clockid_t clock, struct timespec *res) return 0; } + +notrace time_t __vdso_time(time_t *t) +{ + const struct vdso_data *vd = __get_datapage(); + time_t result = READ_ONCE(vd->xtime_coarse_sec); + + if (t) + *t = result; + return result; +}