| // SPDX-License-Identifier: GPL-2.0-only |
| /* |
| * Copyright (C) 2011 Richard Weinberger <richrd@nod.at> |
| * |
| * This vDSO turns all calls into a syscall so that UML can trap them. |
| */ |
| |
| |
| /* Disable profiling for userspace code */ |
| #define DISABLE_BRANCH_PROFILING |
| |
| #include <linux/time.h> |
| #include <linux/getcpu.h> |
| #include <asm/unistd.h> |
| |
| /* workaround for -Wmissing-prototypes warnings */ |
| int __vdso_clock_gettime(clockid_t clock, struct __kernel_old_timespec *ts); |
| int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz); |
| __kernel_old_time_t __vdso_time(__kernel_old_time_t *t); |
| long __vdso_getcpu(unsigned int *cpu, unsigned int *node, struct getcpu_cache *unused); |
| |
| int __vdso_clock_gettime(clockid_t clock, struct __kernel_old_timespec *ts) |
| { |
| long ret; |
| |
| asm("syscall" |
| : "=a" (ret) |
| : "0" (__NR_clock_gettime), "D" (clock), "S" (ts) |
| : "rcx", "r11", "memory"); |
| |
| return ret; |
| } |
| int clock_gettime(clockid_t, struct __kernel_old_timespec *) |
| __attribute__((weak, alias("__vdso_clock_gettime"))); |
| |
| int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz) |
| { |
| long ret; |
| |
| asm("syscall" |
| : "=a" (ret) |
| : "0" (__NR_gettimeofday), "D" (tv), "S" (tz) |
| : "rcx", "r11", "memory"); |
| |
| return ret; |
| } |
| int gettimeofday(struct __kernel_old_timeval *, struct timezone *) |
| __attribute__((weak, alias("__vdso_gettimeofday"))); |
| |
| __kernel_old_time_t __vdso_time(__kernel_old_time_t *t) |
| { |
| long secs; |
| |
| asm volatile("syscall" |
| : "=a" (secs) |
| : "0" (__NR_time), "D" (t) : "cc", "r11", "cx", "memory"); |
| |
| return secs; |
| } |
| __kernel_old_time_t time(__kernel_old_time_t *t) __attribute__((weak, alias("__vdso_time"))); |
| |
| long |
| __vdso_getcpu(unsigned int *cpu, unsigned int *node, struct getcpu_cache *unused) |
| { |
| /* |
| * UML does not support SMP, we can cheat here. :) |
| */ |
| |
| if (cpu) |
| *cpu = 0; |
| if (node) |
| *node = 0; |
| |
| return 0; |
| } |
| |
| long getcpu(unsigned int *cpu, unsigned int *node, struct getcpu_cache *tcache) |
| __attribute__((weak, alias("__vdso_getcpu"))); |