qemu
78 строк · 1.6 Кб
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:
24mov $\nr, %eax
25syscall
26ret
27endf __vdso_\name
28weakalias \name
29.endm
30
31.cfi_startproc
32
33vdso_syscall clock_gettime, __NR_clock_gettime
34vdso_syscall clock_getres, __NR_clock_getres
35vdso_syscall gettimeofday, __NR_gettimeofday
36vdso_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*/
55xor %ecx, %ecx /* rdtscp w/ tsc_aux = 0 */
56
57/* if (cpu != NULL) *cpu = (ecx & 0xfff); */
58test %rdi, %rdi
59jz 1f
60mov %ecx, %eax
61and $0xfff, %eax
62mov %eax, (%rdi)
63
64/* if (node != NULL) *node = (ecx >> 12); */
651: test %rsi, %rsi
66jz 2f
67shr $12, %ecx
68mov %ecx, (%rsi)
69
702: xor %eax, %eax
71ret
72endf __vdso_getcpu
73
74weakalias getcpu
75
76.cfi_endproc
77
78/* TODO: Add elf note for LINUX_VERSION_CODE */
79