diff --git a/sys/amd64/linux/linux_vdso_gtod.c b/sys/amd64/linux/linux_vdso_gtod.c index ad23dc33575a..57d3f4b45dd4 100644 --- a/sys/amd64/linux/linux_vdso_gtod.c +++ b/sys/amd64/linux/linux_vdso_gtod.c @@ -1,146 +1,145 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2021 Dmitry Chagin * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #define _KERNEL #include #undef _KERNEL #include -#include #include #include #include #include #include #include /* The kernel fixup this at vDSO install */ uintptr_t *kern_timekeep_base = NULL; uint32_t kern_tsc_selector = 0; #include /* for debug purpose */ static int write(int fd, const void *buf, size_t size) { int res; __asm__ __volatile__ ( "syscall" : "=a"(res) : "a"(LINUX_SYS_write), "D"(fd), "S"(buf), "d"(size) : "cc", "rcx", "r11", "memory" ); return (res); } static int __vdso_clock_gettime_fallback(clockid_t clock_id, struct l_timespec *ts) { int res; __asm__ __volatile__ ( "syscall" : "=a"(res) : "a"(LINUX_SYS_linux_clock_gettime), "D"(clock_id), "S"(ts) : "cc", "rcx", "r11", "memory" ); return (res); } static int __vdso_gettimeofday_fallback(l_timeval *tv, struct timezone *tz) { int res; __asm__ __volatile__ ( "syscall" : "=a"(res) : "a"(LINUX_SYS_gettimeofday), "D"(tv), "S"(tz) : "cc", "rcx", "r11", "memory" ); return (res); } static int __vdso_clock_getres_fallback(clockid_t clock_id, struct l_timespec *ts) { int res; __asm__ __volatile__ ( "syscall" : "=a"(res) : "a"(LINUX_SYS_linux_clock_getres), "D"(clock_id), "S"(ts) : "cc", "rcx", "r11", "memory" ); return (res); } static int __vdso_getcpu_fallback(uint32_t *cpu, uint32_t *node, void *cache) { int res; __asm__ __volatile__ ( "syscall" : "=a"(res) : "a"(LINUX_SYS_linux_getcpu), "D"(cpu), "S"(node), "d"(cache) : "cc", "rcx", "r11", "memory" ); return (res); } static int __vdso_time_fallback(long *tm) { int res; __asm__ __volatile__ ( "syscall" : "=a"(res) : "a"(LINUX_SYS_linux_time), "D"(tm) : "cc", "rcx", "r11", "memory" ); return (res); } #include diff --git a/sys/amd64/linux32/linux32_vdso_gtod.c b/sys/amd64/linux32/linux32_vdso_gtod.c index f1573ca3c1b1..0caf787c9503 100644 --- a/sys/amd64/linux32/linux32_vdso_gtod.c +++ b/sys/amd64/linux32/linux32_vdso_gtod.c @@ -1,146 +1,145 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2021 Dmitry Chagin * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #define _KERNEL #include #undef _KERNEL #include -#include #include #include #include #include #include #include /* The kernel fixup this at vDSO install */ uintptr_t *kern_timekeep_base = NULL; uint32_t kern_tsc_selector = 0; #include static int write(int fd, const void *buf, size_t size) { int res; __asm__ __volatile__ ( "int $0x80" : "=a"(res) : "a"(LINUX32_SYS_write), "b"(fd), "c"(buf), "d"(size) : "cc", "memory" ); return (res); } static int __vdso_clock_gettime_fallback(clockid_t clock_id, struct l_timespec *ts) { int res; __asm__ __volatile__ ( "int $0x80" : "=a"(res) : "a"(LINUX32_SYS_linux_clock_gettime), "b"(clock_id), "c"(ts) : "cc", "memory" ); return (res); } static int __vdso_clock_gettime64_fallback(clockid_t clock_id, struct l_timespec64 *ts) { int res; __asm__ __volatile__ ( "int $0x80" : "=a"(res) : "a"(LINUX32_SYS_linux_clock_gettime64), "b"(clock_id), "c"(ts) : "cc", "memory" ); return (res); } static int __vdso_gettimeofday_fallback(l_timeval *tv, struct timezone *tz) { int res; __asm__ __volatile__ ( "int $0x80" : "=a"(res) : "a"(LINUX32_SYS_linux_gettimeofday), "b"(tv), "c"(tz) : "cc", "memory" ); return (res); } static int __vdso_clock_getres_fallback(clockid_t clock_id, struct l_timespec *ts) { int res; __asm__ __volatile__ ( "int $0x80" : "=a"(res) : "a"(LINUX32_SYS_linux_clock_getres), "b"(clock_id), "c"(ts) : "cc", "memory" ); return (res); } static int __vdso_time_fallback(long *tm) { int res; __asm__ __volatile__ ( "int $0x80" : "=a"(res) : "a"(LINUX32_SYS_linux_time), "b"(tm) : "cc", "memory" ); return (res); } #include diff --git a/sys/arm64/linux/linux_vdso_gtod.c b/sys/arm64/linux/linux_vdso_gtod.c index 682735cf2fa1..6fdff8335f5d 100644 --- a/sys/arm64/linux/linux_vdso_gtod.c +++ b/sys/arm64/linux/linux_vdso_gtod.c @@ -1,153 +1,152 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2012 Konstantin Belousov * Copyright (c) 2021 Dmitry Chagin * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #define _KERNEL #include #undef _KERNEL #include -#include #include #include #include #include #include #include /* The kernel fixup this at vDSO install */ uintptr_t *kern_timekeep_base = NULL; uint32_t kern_tsc_selector = 0; static int write(int lfd, const void *lbuf, size_t lsize) { register long svc asm("x8") = LINUX_SYS_write; register int fd asm("x0") = lfd; register const char *buf asm("x1") = lbuf; register long size asm("x2") = lsize; register long res asm ("x0"); asm volatile( " svc #0\n" : "=r" (res) : "r" (fd), "r" (buf), "r" (size), "r" (svc) : "memory"); return (res); } static int __vdso_clock_gettime_fallback(clockid_t clock_id, struct l_timespec *lts) { register long svc asm("x8") = LINUX_SYS_linux_clock_gettime; register clockid_t clockid asm("x0") = clock_id; register struct l_timespec *ts asm("x1") = lts; register long res asm ("x0"); asm volatile( " svc #0\n" : "=r" (res) : "r" (clockid), "r" (ts), "r" (svc) : "memory"); return (res); } static int __vdso_gettimeofday_fallback(l_timeval *ltv, struct timezone *ltz) { register long svc asm("x8") = LINUX_SYS_gettimeofday; register l_timeval *tv asm("x0") = ltv; register struct timezone *tz asm("x1") = ltz; register long res asm ("x0"); asm volatile( " svc #0\n" : "=r" (res) : "r" (tv), "r" (tz), "r" (svc) : "memory"); return (res); } static int __vdso_clock_getres_fallback(clockid_t clock_id, struct l_timespec *lts) { register long svc asm("x8") = LINUX_SYS_linux_clock_getres; register clockid_t clockid asm("x0") = clock_id; register struct l_timespec *ts asm("x1") = lts; register long res asm ("x0"); asm volatile( " svc #0\n" : "=r" (res) : "r" (clockid), "r" (ts), "r" (svc) : "memory"); return (res); } /* * copied from lib/libc/aarch64/sys/__vdso_gettc.c */ static inline uint64_t cp15_cntvct_get(void) { uint64_t reg; __asm __volatile("mrs %0, cntvct_el0" : "=r" (reg)); return (reg); } static inline uint64_t cp15_cntpct_get(void) { uint64_t reg; __asm __volatile("mrs %0, cntpct_el0" : "=r" (reg)); return (reg); } int __vdso_gettc(const struct vdso_timehands *th, u_int *tc) { if (th->th_algo != VDSO_TH_ALGO_ARM_GENTIM) return (ENOSYS); __asm __volatile("isb" : : : "memory"); *tc = th->th_physical == 0 ? cp15_cntvct_get() : cp15_cntpct_get(); return (0); } #include diff --git a/sys/compat/linux/linux_vdso_gtod.inc b/sys/compat/linux/linux_vdso_gtod.inc index a90b7dc8efdf..52fab2bbc5d7 100644 --- a/sys/compat/linux/linux_vdso_gtod.inc +++ b/sys/compat/linux/linux_vdso_gtod.inc @@ -1,337 +1,371 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2012 Konstantin Belousov * Copyright (c) 2021 Dmitry Chagin * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ +static int +fls(int mask) +{ + + if (mask == 0) + return (0); + return ((__builtin_clz(mask) ^ 0x1f) + 1); +} + +#ifdef _LP64 +static int +ffsl(long mask) +{ + int bit; + + if (mask == 0) + return (0); + for (bit = 1; !(mask & 1); bit++) + mask = (unsigned long)mask >> 1; + return (bit); +} +#else +static int +ffsll(long long mask) +{ + int bit; + + if (mask == 0) + return (0); + for (bit = 1; !(mask & 1); bit++) + mask = (unsigned long long)mask >> 1; + return (bit); +} +#endif static int __vdso_native_to_linux_timespec(struct l_timespec *lts, struct timespec *nts) { #ifdef COMPAT_LINUX32 if (nts->tv_sec > INT_MAX || nts->tv_sec < INT_MIN) return (LINUX_EOVERFLOW); #endif lts->tv_sec = nts->tv_sec; lts->tv_nsec = nts->tv_nsec; return (0); } static int __vdso_native_to_linux_timeval(l_timeval *ltv, struct timeval *ntv) { #ifdef COMPAT_LINUX32 if (ntv->tv_sec > INT_MAX || ntv->tv_sec < INT_MIN) return (LINUX_EOVERFLOW); #endif ltv->tv_sec = ntv->tv_sec; ltv->tv_usec = ntv->tv_usec; return (0); } #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) static int __vdso_native_to_linux_timespec64(struct l_timespec64 *lts, struct timespec *nts) { lts->tv_sec = nts->tv_sec; lts->tv_nsec = nts->tv_nsec; return (0); } #endif static int __vdso_linux_to_native_clockid(clockid_t *n, clockid_t l) { switch (l) { case LINUX_CLOCK_REALTIME: *n = CLOCK_REALTIME; break; case LINUX_CLOCK_MONOTONIC: *n = CLOCK_MONOTONIC; break; case LINUX_CLOCK_REALTIME_COARSE: *n = CLOCK_REALTIME_FAST; break; case LINUX_CLOCK_MONOTONIC_COARSE: case LINUX_CLOCK_MONOTONIC_RAW: *n = CLOCK_MONOTONIC_FAST; break; case LINUX_CLOCK_BOOTTIME: *n = CLOCK_UPTIME; break; default: return (LINUX_EINVAL); } return (0); } /* * The code below adapted from * lib/libc/sys/__vdso_gettimeofday.c */ static inline void __vdso_gettimekeep(struct vdso_timekeep **tk) { *tk = (struct vdso_timekeep *)kern_timekeep_base; } static int tc_delta(const struct vdso_timehands *th, u_int *delta) { int error; u_int tc; error = __vdso_gettc(th, &tc); if (error == 0) *delta = (tc - th->th_offset_count) & th->th_counter_mask; return (error); } /* * Calculate the absolute or boot-relative time from the * machine-specific fast timecounter and the published timehands * structure read from the shared page. * * The lockless reading scheme is similar to the one used to read the * in-kernel timehands, see sys/kern/kern_tc.c:binuptime(). This code * is based on the kernel implementation. */ static int freebsd_binuptime(struct bintime *bt, struct vdso_timekeep *tk, bool abs) { struct vdso_timehands *th; uint32_t curr, gen; uint64_t scale, x; u_int delta, scale_bits; int error; do { if (!tk->tk_enabled) return (ENOSYS); curr = atomic_load_acq_32(&tk->tk_current); th = &tk->tk_th[curr]; gen = atomic_load_acq_32(&th->th_gen); *bt = th->th_offset; error = tc_delta(th, &delta); if (error == EAGAIN) continue; if (error != 0) return (error); scale = th->th_scale; #ifdef _LP64 scale_bits = ffsl(scale); #else scale_bits = ffsll(scale); #endif if (__predict_false(scale_bits + fls(delta) > 63)) { x = (scale >> 32) * delta; scale &= 0xffffffff; bt->sec += x >> 32; bintime_addx(bt, x << 32); } bintime_addx(bt, scale * delta); if (abs) bintime_add(bt, &th->th_boottime); /* * Ensure that the load of th_offset is completed * before the load of th_gen. */ atomic_thread_fence_acq(); } while (curr != tk->tk_current || gen == 0 || gen != th->th_gen); return (0); } static int freebsd_getnanouptime(struct bintime *bt, struct vdso_timekeep *tk) { struct vdso_timehands *th; uint32_t curr, gen; do { if (!tk->tk_enabled) return (ENOSYS); curr = atomic_load_acq_32(&tk->tk_current); th = &tk->tk_th[curr]; gen = atomic_load_acq_32(&th->th_gen); *bt = th->th_offset; /* * Ensure that the load of th_offset is completed * before the load of th_gen. */ atomic_thread_fence_acq(); } while (curr != tk->tk_current || gen == 0 || gen != th->th_gen); return (0); } static int freebsd_gettimeofday(struct timeval *tv, struct timezone *tz) { struct vdso_timekeep *tk; struct bintime bt; int error; if (tz != NULL) return (ENOSYS); __vdso_gettimekeep(&tk); if (tk == NULL) return (ENOSYS); if (tk->tk_ver != VDSO_TK_VER_CURR) return (ENOSYS); error = freebsd_binuptime(&bt, tk, true); if (error == 0) bintime2timeval(&bt, tv); return (error); } static int freebsd_clock_gettime(clockid_t clock_id, struct timespec *ts) { struct vdso_timekeep *tk; struct bintime bt; int error; __vdso_gettimekeep(&tk); if (tk == NULL) return (ENOSYS); if (tk->tk_ver != VDSO_TK_VER_CURR) return (ENOSYS); switch (clock_id) { case CLOCK_REALTIME: case CLOCK_REALTIME_PRECISE: case CLOCK_REALTIME_FAST: error = freebsd_binuptime(&bt, tk, true); break; case CLOCK_MONOTONIC: case CLOCK_MONOTONIC_PRECISE: case CLOCK_UPTIME: case CLOCK_UPTIME_PRECISE: error = freebsd_binuptime(&bt, tk, false); break; case CLOCK_MONOTONIC_FAST: case CLOCK_UPTIME_FAST: error = freebsd_getnanouptime(&bt, tk); break; default: error = ENOSYS; break; } if (error == 0) bintime2timespec(&bt, ts); return (error); } /* * Linux vDSO interfaces * */ int __vdso_clock_gettime(clockid_t clock_id, struct l_timespec *lts) { struct timespec ts; clockid_t which; int error; error = __vdso_linux_to_native_clockid(&which, clock_id); if (error != 0) return (__vdso_clock_gettime_fallback(clock_id, lts)); error = freebsd_clock_gettime(which, &ts); if (error == 0) return (-__vdso_native_to_linux_timespec(lts, &ts)); else return (__vdso_clock_gettime_fallback(clock_id, lts)); } int __vdso_gettimeofday(l_timeval *ltv, struct timezone *tz) { struct timeval tv; int error; error = freebsd_gettimeofday(&tv, tz); if (error != 0) return (__vdso_gettimeofday_fallback(ltv, tz)); return (-__vdso_native_to_linux_timeval(ltv, &tv)); } int __vdso_clock_getres(clockid_t clock_id, struct l_timespec *lts) { return (__vdso_clock_getres_fallback(clock_id, lts)); } #if defined(__i386__) || defined(COMPAT_LINUX32) int __vdso_clock_gettime64(clockid_t clock_id, struct l_timespec64 *lts) { struct timespec ts; clockid_t which; int error; error = __vdso_linux_to_native_clockid(&which, clock_id); if (error != 0) return (__vdso_clock_gettime64_fallback(clock_id, lts)); error = freebsd_clock_gettime(which, &ts); if (error == 0) return(-__vdso_native_to_linux_timespec64(lts, &ts)); else return(__vdso_clock_gettime64_fallback(clock_id, lts)); } int clock_gettime64(clockid_t clock_id, struct l_timespec64 *lts) __attribute__((weak, alias("__vdso_clock_gettime64"))); #endif #if defined(__amd64__) && !defined(COMPAT_LINUX32) int __vdso_getcpu(uint32_t *cpu, uint32_t *node, void *cache) { return (__vdso_getcpu_fallback(cpu, node, cache)); } #endif #if defined(__i386__) || defined(__amd64__) int __vdso_time(long *tm) { return (__vdso_time_fallback(tm)); } #endif diff --git a/sys/i386/linux/linux_vdso_gtod.c b/sys/i386/linux/linux_vdso_gtod.c index b1e4a4620ee4..046b864c54f5 100644 --- a/sys/i386/linux/linux_vdso_gtod.c +++ b/sys/i386/linux/linux_vdso_gtod.c @@ -1,145 +1,144 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2021 Dmitry Chagin * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #define _KERNEL #include #undef _KERNEL #include -#include #include #include #include #include #include #include /* The kernel fixup this at vDSO install */ uintptr_t *kern_timekeep_base = NULL; uint32_t kern_tsc_selector = 0; #include static int write(int fd, const void *buf, size_t size) { int res; __asm__ __volatile__ ( "int $0x80" : "=a"(res) : "a"(LINUX_SYS_write), "b"(fd), "c"(buf), "d"(size) : "cc", "memory" ); return (res); } static int __vdso_clock_gettime_fallback(clockid_t clock_id, struct l_timespec *ts) { int res; __asm__ __volatile__ ( "int $0x80" : "=a"(res) : "a"(LINUX_SYS_linux_clock_gettime), "b"(clock_id), "c"(ts) : "cc", "memory" ); return (res); } static int __vdso_clock_gettime64_fallback(clockid_t clock_id, struct l_timespec64 *ts) { int res; __asm__ __volatile__ ( "int $0x80" : "=a"(res) : "a"(LINUX_SYS_linux_clock_gettime64), "b"(clock_id), "c"(ts) : "cc", "memory" ); return (res); } static int __vdso_gettimeofday_fallback(l_timeval *tv, struct timezone *tz) { int res; __asm__ __volatile__ ( "int $0x80" : "=a"(res) : "a"(LINUX_SYS_gettimeofday), "b"(tv), "c"(tz) : "cc", "memory" ); return (res); } static int __vdso_clock_getres_fallback(clockid_t clock_id, struct l_timespec *ts) { int res; __asm__ __volatile__ ( "int $0x80" : "=a"(res) : "a"(LINUX_SYS_linux_clock_getres), "b"(clock_id), "c"(ts) : "cc", "memory" ); return (res); } static int __vdso_time_fallback(long *tm) { int res; __asm__ __volatile__ ( "int $0x80" : "=a"(res) : "a"(LINUX_SYS_linux_time), "b"(tm) : "cc", "memory" ); return (res); } #include