system_call.S 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * AT_SYSINFO entry point
  4. */
  5. #include <linux/linkage.h>
  6. #include <asm/dwarf2.h>
  7. #include <asm/cpufeatures.h>
  8. #include <asm/alternative-asm.h>
  9. .text
  10. .globl __kernel_vsyscall
  11. .type __kernel_vsyscall,@function
  12. ALIGN
  13. __kernel_vsyscall:
  14. CFI_STARTPROC
  15. /*
  16. * Reshuffle regs so that all of any of the entry instructions
  17. * will preserve enough state.
  18. *
  19. * A really nice entry sequence would be:
  20. * pushl %edx
  21. * pushl %ecx
  22. * movl %esp, %ecx
  23. *
  24. * Unfortunately, naughty Android versions between July and December
  25. * 2015 actually hardcode the traditional Linux SYSENTER entry
  26. * sequence. That is severely broken for a number of reasons (ask
  27. * anyone with an AMD CPU, for example). Nonetheless, we try to keep
  28. * it working approximately as well as it ever worked.
  29. *
  30. * This link may eludicate some of the history:
  31. * https://android-review.googlesource.com/#/q/Iac3295376d61ef83e713ac9b528f3b50aa780cd7
  32. * personally, I find it hard to understand what's going on there.
  33. *
  34. * Note to future user developers: DO NOT USE SYSENTER IN YOUR CODE.
  35. * Execute an indirect call to the address in the AT_SYSINFO auxv
  36. * entry. That is the ONLY correct way to make a fast 32-bit system
  37. * call on Linux. (Open-coding int $0x80 is also fine, but it's
  38. * slow.)
  39. */
  40. pushl %ecx
  41. CFI_ADJUST_CFA_OFFSET 4
  42. CFI_REL_OFFSET ecx, 0
  43. pushl %edx
  44. CFI_ADJUST_CFA_OFFSET 4
  45. CFI_REL_OFFSET edx, 0
  46. pushl %ebp
  47. CFI_ADJUST_CFA_OFFSET 4
  48. CFI_REL_OFFSET ebp, 0
  49. #define SYSENTER_SEQUENCE "movl %esp, %ebp; sysenter"
  50. #define SYSCALL_SEQUENCE "movl %ecx, %ebp; syscall"
  51. #ifdef CONFIG_X86_64
  52. /* If SYSENTER (Intel) or SYSCALL32 (AMD) is available, use it. */
  53. ALTERNATIVE_2 "", SYSENTER_SEQUENCE, X86_FEATURE_SYSENTER32, \
  54. SYSCALL_SEQUENCE, X86_FEATURE_SYSCALL32
  55. #else
  56. ALTERNATIVE "", SYSENTER_SEQUENCE, X86_FEATURE_SEP
  57. #endif
  58. /* Enter using int $0x80 */
  59. int $0x80
  60. GLOBAL(int80_landing_pad)
  61. /*
  62. * Restore EDX and ECX in case they were clobbered. EBP is not
  63. * clobbered (the kernel restores it), but it's cleaner and
  64. * probably faster to pop it than to adjust ESP using addl.
  65. */
  66. popl %ebp
  67. CFI_RESTORE ebp
  68. CFI_ADJUST_CFA_OFFSET -4
  69. popl %edx
  70. CFI_RESTORE edx
  71. CFI_ADJUST_CFA_OFFSET -4
  72. popl %ecx
  73. CFI_RESTORE ecx
  74. CFI_ADJUST_CFA_OFFSET -4
  75. ret
  76. CFI_ENDPROC
  77. .size __kernel_vsyscall,.-__kernel_vsyscall
  78. .previous