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