/* * x86-64 linux replacement vdso. * * Copyright 2023 Linaro, Ltd. * * SPDX-License-Identifier: GPL-2.0-or-later */ #include .macro endf name .globl \name .type \name, @function .size \name, . - \name .endm .macro weakalias name \name = __vdso_\name .weak \name .endm .macro vdso_syscall name, nr __vdso_\name: mov $\nr, %eax syscall ret endf __vdso_\name weakalias \name .endm .cfi_startproc vdso_syscall clock_gettime, __NR_clock_gettime vdso_syscall clock_getres, __NR_clock_getres vdso_syscall gettimeofday, __NR_gettimeofday vdso_syscall time, __NR_time __vdso_getcpu: /* * There is no syscall number for this allocated on x64. * We can handle this several ways: * * (1) Invent a syscall number for use within qemu. * It should be easy enough to pick a number that * is well out of the way of the kernel numbers. * * (2) Force the emulated cpu to support the rdtscp insn, * and initialize the TSC_AUX value the appropriate value. * * (3) Pretend that we're always running on cpu 0. * * This last is the one that's implemented here, with the * tiny bit of extra code to support rdtscp in place. */ xor %ecx, %ecx /* rdtscp w/ tsc_aux = 0 */ /* if (cpu != NULL) *cpu = (ecx & 0xfff); */ test %rdi, %rdi jz 1f mov %ecx, %eax and $0xfff, %eax mov %eax, (%rdi) /* if (node != NULL) *node = (ecx >> 12); */ 1: test %rsi, %rsi jz 2f shr $12, %ecx mov %ecx, (%rsi) 2: xor %eax, %eax ret endf __vdso_getcpu weakalias getcpu .cfi_endproc /* TODO: Add elf note for LINUX_VERSION_CODE */