getuser_64.S 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*
  2. * __get_user functions.
  3. *
  4. * (C) Copyright 1998 Linus Torvalds
  5. * (C) Copyright 2005 Andi Kleen
  6. *
  7. * These functions have a non-standard call interface
  8. * to make them more efficient, especially as they
  9. * return an error value in addition to the "real"
  10. * return value.
  11. */
  12. /*
  13. * __get_user_X
  14. *
  15. * Inputs: %rcx contains the address.
  16. * The register is modified, but all changes are undone
  17. * before returning because the C code doesn't know about it.
  18. *
  19. * Outputs: %rax is error code (0 or -EFAULT)
  20. * %rdx contains zero-extended value
  21. *
  22. * %r8 is destroyed.
  23. *
  24. * These functions should not modify any other registers,
  25. * as they get called from within inline assembly.
  26. */
  27. #include <linux/linkage.h>
  28. #include <asm/dwarf2.h>
  29. #include <asm/page.h>
  30. #include <asm/errno.h>
  31. #include <asm/asm-offsets.h>
  32. #include <asm/thread_info.h>
  33. .text
  34. ENTRY(__get_user_1)
  35. CFI_STARTPROC
  36. GET_THREAD_INFO(%rdx)
  37. cmpq threadinfo_addr_limit(%rdx),%rax
  38. jae bad_get_user
  39. 1: movzb (%rax),%edx
  40. xorl %eax,%eax
  41. ret
  42. CFI_ENDPROC
  43. ENDPROC(__get_user_1)
  44. ENTRY(__get_user_2)
  45. CFI_STARTPROC
  46. addq $1,%rax
  47. jc bad_get_user
  48. GET_THREAD_INFO(%rdx)
  49. cmpq threadinfo_addr_limit(%rdx),%rax
  50. jae bad_get_user
  51. 2: movzwl -1(%rax),%edx
  52. xorl %eax,%eax
  53. ret
  54. CFI_ENDPROC
  55. ENDPROC(__get_user_2)
  56. ENTRY(__get_user_4)
  57. CFI_STARTPROC
  58. addq $3,%rax
  59. jc bad_get_user
  60. GET_THREAD_INFO(%rdx)
  61. cmpq threadinfo_addr_limit(%rdx),%rax
  62. jae bad_get_user
  63. 3: movl -3(%rax),%edx
  64. xorl %eax,%eax
  65. ret
  66. CFI_ENDPROC
  67. ENDPROC(__get_user_4)
  68. ENTRY(__get_user_8)
  69. CFI_STARTPROC
  70. addq $7,%rax
  71. jc bad_get_user
  72. GET_THREAD_INFO(%rdx)
  73. cmpq threadinfo_addr_limit(%rdx),%rax
  74. jae bad_get_user
  75. 4: movq -7(%rax),%rdx
  76. xorl %eax,%eax
  77. ret
  78. CFI_ENDPROC
  79. ENDPROC(__get_user_8)
  80. bad_get_user:
  81. CFI_STARTPROC
  82. xorl %edx,%edx
  83. movq $(-EFAULT),%rax
  84. ret
  85. CFI_ENDPROC
  86. END(bad_get_user)
  87. .section __ex_table,"a"
  88. .quad 1b,bad_get_user
  89. .quad 2b,bad_get_user
  90. .quad 3b,bad_get_user
  91. .quad 4b,bad_get_user
  92. .previous