enter_enclave.S 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. /*
  2. * Copyright (C) 2011-2018 Intel Corporation. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in
  12. * the documentation and/or other materials provided with the
  13. * distribution.
  14. * * Neither the name of Intel Corporation nor the names of its
  15. * contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. *
  30. */
  31. #include "enter_enclave.h"
  32. /* int __morestack(const tcs_t *tcs, const int fn, const void *ocall_table, const void *ms, CTrustThread *trust_thread); */
  33. .file "enter_enclave.S"
  34. .data
  35. g_xsave_size: .long 0
  36. g_clean_ymm: .long 0
  37. .text
  38. DECLARE_GLOBAL_FUNC set_xsave_info
  39. #if defined(LINUX32)
  40. mov SE_WORDSIZE*1(%esp), %ecx
  41. mov SE_WORDSIZE*2(%esp), %edx
  42. #else
  43. mov %rdi, %rcx
  44. mov %rsi, %rdx
  45. #endif
  46. lea_symbol g_xsave_size, %xax
  47. movl %ecx, (%xax)
  48. lea_symbol g_clean_ymm, %xax
  49. movl %edx, (%xax)
  50. ret
  51. DECLARE_GLOBAL_FUNC __morestack
  52. //__morestack:
  53. EENTER_PROLOG
  54. movl frame_arg1, %edi /* fn */
  55. #if defined(__x86_64__)
  56. /* we defined fn as int, so we do sign extend.*/
  57. movslq %edi, %rdi
  58. #endif
  59. mov frame_arg3, %xsi /* ms */
  60. .Ldo_eenter:
  61. # clean the upper bits of YMM registers
  62. lea_symbol g_clean_ymm, %xbx
  63. movl (%xbx), %ecx
  64. cmpl $0, %ecx
  65. je 1f
  66. vzeroupper
  67. 1:
  68. mov frame_arg0, %xbx /* tcs addr */
  69. lea_pic .Lasync_exit_pointer, %xcx /* aep addr */
  70. mov $SE_EENTER, %xax /* EENTER leaf */
  71. .Leenter_inst:
  72. ENCLU
  73. /*
  74. * at this point, we may have returned due to a normal EEXIT,
  75. * or we may have returned due to an OCALL. We differentiate
  76. * by popping the top of the stack. If it is not OCMD_ERET, we have
  77. * an untrusted bridge to call at that address.
  78. */
  79. /* We have an ocall. Call our bridge function. */
  80. cmp $OCMD_ERET, %xdi
  81. je .Leret
  82. .Ldo_ocall:
  83. /* call ocall
  84. * int ocall(const unsigned int proc, void *ocall_table, const void *ms, CEnclave *enclave);
  85. *
  86. * When EEXIT'ed from tRTS due to an OCALL,
  87. * - `rdi' holds OCALL index
  88. *- `rsi' holds the pointer to marshalling structure
  89. */
  90. .type sgx_ocall,@function
  91. .hidden sgx_ocall
  92. #if defined(__i386__)
  93. sub $(3*SE_WORDSIZE), %xsp /* make stack 16 bytes aligned */
  94. push frame_arg0
  95. push frame_arg4
  96. push %esi
  97. push frame_arg2
  98. push %edi
  99. #endif
  100. #if defined(__x86_64__)
  101. mov %rsi, %rdx /* param2 */
  102. /*mov %rdi, %rdi */ /* param0 */
  103. mov frame_arg2, %rsi /* param1 */
  104. mov frame_arg4, %rcx /* param3 */
  105. mov frame_arg0, %r8 /* param4 */
  106. #endif
  107. call stack_sticker
  108. xor %xsi, %xsi
  109. mov %eax, %esi
  110. cmp $SE_ERROR_READ_LOCK_FAIL, %esi
  111. je .Loret
  112. mov $ECMD_ORET, %xdi /* oret */
  113. jmp .Ldo_eenter
  114. /* never return here */
  115. ud2
  116. .Leret:
  117. .Loret:
  118. EENTER_EPILOG
  119. .Lasync_exit_pointer:
  120. ENCLU
  121. .size __morestack, .-__morestack
  122. DECLARE_GLOBAL_FUNC get_aep
  123. lea_pic .Lasync_exit_pointer, %xax
  124. ret
  125. DECLARE_GLOBAL_FUNC get_eenterp
  126. lea_pic .Leenter_inst, %xax
  127. ret
  128. DECLARE_GLOBAL_FUNC get_eretp
  129. lea_pic .Leret, %xax
  130. ret
  131. /*
  132. * function stack_sticker is the wrapper of ocall,
  133. * before call ocall, update the ret address and frame pointer (BP) on the stack
  134. *
  135. * Stack before:
  136. * |__morestack stack |<--|
  137. * ------------- |
  138. * |return adress | |
  139. * xbp -> | caller xbp | --|
  140. * | |
  141. * xsp -> | |
  142. * -------------
  143. *
  144. * Stack after:
  145. * |__morestack stack |
  146. * ------------------
  147. * | __morestack(inside)|
  148. * xbp -> | xbp_t | ---->the frame point of __morestack
  149. * | |
  150. * xsp -> | |
  151. * | <ecall> |
  152. * ------------------
  153. * int stack_sticker(unsigned int proc, sgx_ocall_table_t *ocall_table, void *ms, CTrustThread *trust_thread, tcs_t *tcs)
  154. */
  155. DECLARE_GLOBAL_FUNC stack_sticker
  156. .hidden stack_sticker
  157. .type push_ocall_frame,@function
  158. .hidden push_ocall_frame
  159. .type pop_ocall_frame,@function
  160. .hidden pop_ocall_frame
  161. .cfi_startproc
  162. push %xbp
  163. .cfi_def_cfa_offset 2*SE_WORDSIZE
  164. .cfi_offset xbp,-2*SE_WORDSIZE
  165. mov %xsp, %xbp
  166. .cfi_def_cfa_register xbp
  167. #if defined(__i386__)
  168. sub $(10*SE_WORDSIZE), %xsp /* We should have the stack 16 bytes aligned */
  169. #elif defined(__x86_64__)
  170. sub $(10*SE_WORDSIZE), %xsp
  171. #endif
  172. /* save the return address and the frame point */
  173. mov (0*SE_WORDSIZE)(%xbp), %xax
  174. mov %xax, (4*SE_WORDSIZE)(%xsp)
  175. mov (1*SE_WORDSIZE)(%xbp), %xax
  176. mov %xax, (5*SE_WORDSIZE)(%xsp)
  177. #if defined(__i386__)
  178. /* save the first 4 parameters */
  179. mov frame_arg0, %xax
  180. mov %xax, (0*SE_WORDSIZE)(%xsp)
  181. mov frame_arg1, %xax
  182. mov %xax, (1*SE_WORDSIZE)(%xsp)
  183. mov frame_arg2, %xax
  184. mov %xax, (2*SE_WORDSIZE)(%xsp)
  185. mov frame_arg3, %xax
  186. mov %xax, (3*SE_WORDSIZE)(%xsp)
  187. /* update the frame infomation */
  188. mov frame_arg3, %xax /* the pointer of trustthread instance */
  189. push %xax
  190. mov frame_arg4, %xax /* tcs */
  191. push %xax
  192. push %xbp
  193. /*just for call push_ocall_frame and return, no stack 16 bytes alignment needed */
  194. call push_ocall_frame
  195. /* recover parameters */
  196. add $(3*SE_WORDSIZE), %xsp
  197. #elif defined(__x86_64__)
  198. /* save the first 4 parameters */
  199. mov %xdi, (0*SE_WORDSIZE)(%xsp)
  200. mov %xsi, (1*SE_WORDSIZE)(%xsp)
  201. mov %xdx, (2*SE_WORDSIZE)(%xsp)
  202. mov %xcx, (3*SE_WORDSIZE)(%xsp)
  203. /* update the frame infomation */
  204. mov %xcx, %xdx /* the pointer of trustthread instance */
  205. mov %r8, %xsi /* tcs */
  206. mov %xbp, %xdi
  207. call push_ocall_frame
  208. /* recover parameters */
  209. mov (0*SE_WORDSIZE)(%xsp), %xdi
  210. mov (1*SE_WORDSIZE)(%xsp), %xsi
  211. mov (2*SE_WORDSIZE)(%xsp), %xdx
  212. mov (3*SE_WORDSIZE)(%xsp), %xcx
  213. #endif
  214. /* start the ocall */
  215. call sgx_ocall
  216. /* save the return value */
  217. mov %xax, (0*SE_WORDSIZE)(%xsp)
  218. #if defined(__i386__)
  219. /* pop the frame infomation */
  220. mov frame_arg3, %xax /* the pointer of trustthread instance */
  221. push %xax
  222. mov frame_arg4, %xax /* tcs is not used for now */
  223. push %xax
  224. call pop_ocall_frame
  225. /* recover parameters */
  226. add $(2*SE_WORDSIZE), %xsp
  227. #elif defined(__x86_64__)
  228. /* pop the frame infomation */
  229. mov (3*SE_WORDSIZE)(%xsp), %xsi /* the pointer of trustthread instance */
  230. call pop_ocall_frame
  231. #endif
  232. /* recover the return address and frame point */
  233. mov (4*SE_WORDSIZE)(%xsp), %xax
  234. mov %xax, (0*SE_WORDSIZE)(%xbp)
  235. mov (5*SE_WORDSIZE)(%xsp), %xax
  236. mov %xax, (1*SE_WORDSIZE)(%xbp)
  237. /* recover the return value */
  238. mov (0*SE_WORDSIZE)(%xsp), %xax
  239. leave
  240. ret
  241. .cfi_endproc
  242. /*
  243. * void sgx_debug_load_state_add_element(debug_enclave_info_t* new_enclave_info, debug_enclave_info_t** g_debug_enclave_info_list)
  244. * On x86, calling convention is "void sgx_debug_load_state_add_element(eax, edx)"
  245. * On x64, calling convention is "void sgx_debug_load_state_add_element(rdi, rsi)"
  246. * Add an new enclave info to list head and raise enclave load event
  247. */
  248. DECLARE_GLOBAL_FUNC sgx_debug_load_state_add_element
  249. #if defined(__i386__)
  250. movl %eax, (%edx)
  251. #else
  252. movq %rdi, (%rsi)
  253. #endif
  254. ret
  255. /*
  256. * void sgx_debug_unload_state_remove_element(debug_enclave_info_t* enclave_info, debug_enclave_info_t** pre_enclave_info, debug_enclave_info_t* next_enclave_info)
  257. * On x86, calling convention is "void se_debug_load_state_remove_element(eax, edx, ecx)"
  258. * On x64, calling convention is "void se_debug_load_state_remove_element(rdi, rsi, rdx)"
  259. * eax is to pass the removed enclave info to debugger.
  260. * Remove an enclave info from list and raise enclave unload event
  261. */
  262. DECLARE_GLOBAL_FUNC sgx_debug_unload_state_remove_element
  263. #if defined(__i386__)
  264. movl %ecx, (%edx)
  265. #else
  266. movq %rdx, (%rsi)
  267. #endif
  268. ret
  269. /* We do not need executable stack.*/
  270. .section .note.GNU-stack,"",@progbits