system_call.S 2.3 KB

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