
The vDSO library should only include the necessary headers required for a userspace library (UAPI and a minimal set of kernel headers). To make this possible it is necessary to isolate from the kernel headers the common parts that are strictly necessary to build the library. Refactor the vdso implementation to include common headers. Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Cc: Will Deacon <will@kernel.org> Link: https://lkml.kernel.org/r/20200320145351.32292-21-vincenzo.frascino@arm.com
102 lines
2.1 KiB
C
102 lines
2.1 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright (C) 2018 ARM Limited
|
|
*/
|
|
#ifndef __ASM_VDSO_GETTIMEOFDAY_H
|
|
#define __ASM_VDSO_GETTIMEOFDAY_H
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
#include <asm/unistd.h>
|
|
|
|
#define VDSO_HAS_CLOCK_GETRES 1
|
|
|
|
static __always_inline
|
|
int gettimeofday_fallback(struct __kernel_old_timeval *_tv,
|
|
struct timezone *_tz)
|
|
{
|
|
register struct timezone *tz asm("x1") = _tz;
|
|
register struct __kernel_old_timeval *tv asm("x0") = _tv;
|
|
register long ret asm ("x0");
|
|
register long nr asm("x8") = __NR_gettimeofday;
|
|
|
|
asm volatile(
|
|
" svc #0\n"
|
|
: "=r" (ret)
|
|
: "r" (tv), "r" (tz), "r" (nr)
|
|
: "memory");
|
|
|
|
return ret;
|
|
}
|
|
|
|
static __always_inline
|
|
long clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
|
|
{
|
|
register struct __kernel_timespec *ts asm("x1") = _ts;
|
|
register clockid_t clkid asm("x0") = _clkid;
|
|
register long ret asm ("x0");
|
|
register long nr asm("x8") = __NR_clock_gettime;
|
|
|
|
asm volatile(
|
|
" svc #0\n"
|
|
: "=r" (ret)
|
|
: "r" (clkid), "r" (ts), "r" (nr)
|
|
: "memory");
|
|
|
|
return ret;
|
|
}
|
|
|
|
static __always_inline
|
|
int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
|
|
{
|
|
register struct __kernel_timespec *ts asm("x1") = _ts;
|
|
register clockid_t clkid asm("x0") = _clkid;
|
|
register long ret asm ("x0");
|
|
register long nr asm("x8") = __NR_clock_getres;
|
|
|
|
asm volatile(
|
|
" svc #0\n"
|
|
: "=r" (ret)
|
|
: "r" (clkid), "r" (ts), "r" (nr)
|
|
: "memory");
|
|
|
|
return ret;
|
|
}
|
|
|
|
static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
|
|
{
|
|
u64 res;
|
|
|
|
/*
|
|
* Core checks for mode already, so this raced against a concurrent
|
|
* update. Return something. Core will do another round and then
|
|
* see the mode change and fallback to the syscall.
|
|
*/
|
|
if (clock_mode == VDSO_CLOCKMODE_NONE)
|
|
return 0;
|
|
|
|
/*
|
|
* This isb() is required to prevent that the counter value
|
|
* is speculated.
|
|
*/
|
|
isb();
|
|
asm volatile("mrs %0, cntvct_el0" : "=r" (res) :: "memory");
|
|
/*
|
|
* This isb() is required to prevent that the seq lock is
|
|
* speculated.#
|
|
*/
|
|
isb();
|
|
|
|
return res;
|
|
}
|
|
|
|
static __always_inline
|
|
const struct vdso_data *__arch_get_vdso_data(void)
|
|
{
|
|
return _vdso_data;
|
|
}
|
|
|
|
#endif /* !__ASSEMBLY__ */
|
|
|
|
#endif /* __ASM_VDSO_GETTIMEOFDAY_H */
|