master
s 78 lines 1.61 KB
Raw
1 /*
2 * x86-64 linux replacement vdso.
3 *
4 * Copyright 2023 Linaro, Ltd.
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8
9 #include <asm/unistd.h>
10
11 .macro endf name
12 .globl \name
13 .type \name, @function
14 .size \name, . - \name
15 .endm
16
17 .macro weakalias name
18 \name = __vdso_\name
19 .weak \name
20 .endm
21
22 .macro vdso_syscall name, nr
23 __vdso_\name:
24 mov $\nr, %eax
25 syscall
26 ret
27 endf __vdso_\name
28 weakalias \name
29 .endm
30
31 .cfi_startproc
32
33 vdso_syscall clock_gettime, __NR_clock_gettime
34 vdso_syscall clock_getres, __NR_clock_getres
35 vdso_syscall gettimeofday, __NR_gettimeofday
36 vdso_syscall time, __NR_time
37
38 __vdso_getcpu:
39 /*
40 * There is no syscall number for this allocated on x64.
41 * We can handle this several ways:
42 *
43 * (1) Invent a syscall number for use within qemu.
44 * It should be easy enough to pick a number that
45 * is well out of the way of the kernel numbers.
46 *
47 * (2) Force the emulated cpu to support the rdtscp insn,
48 * and initialize the TSC_AUX value the appropriate value.
49 *
50 * (3) Pretend that we're always running on cpu 0.
51 *
52 * This last is the one that's implemented here, with the
53 * tiny bit of extra code to support rdtscp in place.
54 */
55 xor %ecx, %ecx /* rdtscp w/ tsc_aux = 0 */
56
57 /* if (cpu != NULL) *cpu = (ecx & 0xfff); */
58 test %rdi, %rdi
59 jz 1f
60 mov %ecx, %eax
61 and $0xfff, %eax
62 mov %eax, (%rdi)
63
64 /* if (node != NULL) *node = (ecx >> 12); */
65 1: test %rsi, %rsi
66 jz 2f
67 shr $12, %ecx
68 mov %ecx, (%rsi)
69
70 2: xor %eax, %eax
71 ret
72 endf __vdso_getcpu
73
74 weakalias getcpu
75
76 .cfi_endproc
77
78 /* TODO: Add elf note for LINUX_VERSION_CODE */