1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * AT_SYSINFO entry point 4*/ 5 6#include <linux/linkage.h> 7#include <asm/dwarf2.h> 8#include <asm/cpufeatures.h> 9#include <asm/alternative.h> 10 11 .text 12 .globl __kernel_vsyscall 13 .type __kernel_vsyscall,@function 14 ALIGN 15__kernel_vsyscall: 16 CFI_STARTPROC 17 18 /* 19 * If using int $0x80, there is no reason to muck about with the 20 * stack here. Unfortunately just overwriting the push instructions 21 * would mess up the CFI annotations, but it is only a 3-byte 22 * NOP in that case. This could be avoided by patching the 23 * vdso symbol table (not the code) and entry point, but that 24 * would a fair bit of tooling work or by simply compiling 25 * two different vDSO images, but that doesn't seem worth it. 26 */ 27 ALTERNATIVE "int $0x80; ret", "", X86_FEATURE_SYSFAST32 28 29 /* 30 * Reshuffle regs so that all of any of the entry instructions 31 * will preserve enough state. 32 * 33 * A really nice entry sequence would be: 34 * pushl %edx 35 * pushl %ecx 36 * movl %esp, %ecx 37 * 38 * Unfortunately, naughty Android versions between July and December 39 * 2015 actually hardcode the traditional Linux SYSENTER entry 40 * sequence. That is severely broken for a number of reasons (ask 41 * anyone with an AMD CPU, for example). Nonetheless, we try to keep 42 * it working approximately as well as it ever worked. 43 * 44 * This link may elucidate some of the history: 45 * https://android-review.googlesource.com/#/q/Iac3295376d61ef83e713ac9b528f3b50aa780cd7 46 * personally, I find it hard to understand what's going on there. 47 * 48 * Note to future user developers: DO NOT USE SYSENTER IN YOUR CODE. 49 * Execute an indirect call to the address in the AT_SYSINFO auxv 50 * entry. That is the ONLY correct way to make a fast 32-bit system 51 * call on Linux. (Open-coding int $0x80 is also fine, but it's 52 * slow.) 53 */ 54 pushl %ecx 55 CFI_ADJUST_CFA_OFFSET 4 56 CFI_REL_OFFSET ecx, 0 57 pushl %edx 58 CFI_ADJUST_CFA_OFFSET 4 59 CFI_REL_OFFSET edx, 0 60 pushl %ebp 61 CFI_ADJUST_CFA_OFFSET 4 62 CFI_REL_OFFSET ebp, 0 63 64 #define SYSENTER_SEQUENCE "movl %esp, %ebp; sysenter" 65 #define SYSCALL_SEQUENCE "movl %ecx, %ebp; syscall" 66 67 ALTERNATIVE SYSENTER_SEQUENCE, SYSCALL_SEQUENCE, X86_FEATURE_SYSCALL32 68 69 /* Re-enter using int $0x80 */ 70 int $0x80 71SYM_INNER_LABEL(int80_landing_pad, SYM_L_GLOBAL) 72 73 /* 74 * Restore EDX and ECX in case they were clobbered. EBP is not 75 * clobbered (the kernel restores it), but it's cleaner and 76 * probably faster to pop it than to adjust ESP using addl. 77 */ 78 popl %ebp 79 CFI_RESTORE ebp 80 CFI_ADJUST_CFA_OFFSET -4 81 popl %edx 82 CFI_RESTORE edx 83 CFI_ADJUST_CFA_OFFSET -4 84 popl %ecx 85 CFI_RESTORE ecx 86 CFI_ADJUST_CFA_OFFSET -4 87 RET 88 CFI_ENDPROC 89 90 .size __kernel_vsyscall,.-__kernel_vsyscall 91 .previous 92