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