sgx_tls.h 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #ifndef __SGX_TLS_H__
  2. #define __SGX_TLS_H__
  3. #include <pal.h>
  4. /*
  5. * Beside the classic thread local storage (like ustack, thread, etc.) the TLS
  6. * area is also used to pass parameters needed during enclave or thread
  7. * initialization. Some of them are thread specific (like tcs_offset) and some
  8. * of them are identical for all threads (like enclave_size).
  9. */
  10. struct enclave_tls {
  11. PAL_TCB common;
  12. struct {
  13. /* private to Linux-SGX PAL */
  14. uint64_t enclave_size;
  15. uint64_t tcs_offset;
  16. uint64_t initial_stack_offset;
  17. uint64_t tmp_rip;
  18. uint64_t sig_stack_low;
  19. uint64_t sig_stack_high;
  20. void* ecall_return_addr;
  21. void* ssa;
  22. sgx_pal_gpr_t* gpr;
  23. void* exit_target;
  24. void* fsbase;
  25. void* pre_ocall_stack;
  26. void* ustack_top;
  27. void* ustack;
  28. struct pal_handle_thread* thread;
  29. uint64_t ocall_exit_called;
  30. uint64_t thread_started;
  31. uint64_t ready_for_exceptions;
  32. uint64_t manifest_size;
  33. void* heap_min;
  34. void* heap_max;
  35. void* exec_addr;
  36. uint64_t exec_size;
  37. int* clear_child_tid;
  38. };
  39. };
  40. #ifndef DEBUG
  41. extern uint64_t dummy_debug_variable;
  42. #endif
  43. # ifdef IN_ENCLAVE
  44. # define GET_ENCLAVE_TLS(member) \
  45. ({ \
  46. struct enclave_tls * tmp; \
  47. uint64_t val; \
  48. static_assert(sizeof(tmp->member) == 8, \
  49. "sgx_tls member should have 8-byte type"); \
  50. __asm__ ("movq %%gs:%c1, %q0": "=r" (val) \
  51. : "i" (offsetof(struct enclave_tls, member))); \
  52. (__typeof(tmp->member)) val; \
  53. })
  54. # define SET_ENCLAVE_TLS(member, value) \
  55. do { \
  56. struct enclave_tls * tmp; \
  57. static_assert(sizeof(tmp->member) == 8, \
  58. "sgx_tls member should have 8-byte type"); \
  59. static_assert(sizeof(value) == 8, \
  60. "only 8-byte type can be set to sgx_tls"); \
  61. __asm__ ("movq %q0, %%gs:%c1":: "r" (value), \
  62. "i" (offsetof(struct enclave_tls, member))); \
  63. } while (0)
  64. # else
  65. /* private to untrusted Linux PAL, unique to each untrusted thread */
  66. typedef struct pal_tcb_urts {
  67. struct pal_tcb_urts* self;
  68. sgx_arch_tcs_t* tcs; /* TCS page of SGX corresponding to thread, for EENTER */
  69. void* stack; /* bottom of stack, for later freeing when thread exits */
  70. void* alt_stack; /* bottom of alt stack, for child thread to init alt stack */
  71. } PAL_TCB_URTS;
  72. extern void pal_tcb_urts_init(PAL_TCB_URTS* tcb, void* stack, void* alt_stack);
  73. static inline PAL_TCB_URTS* get_tcb_urts(void) {
  74. PAL_TCB_URTS* tcb;
  75. __asm__ ("movq %%gs:%c1, %q0\n"
  76. : "=r" (tcb)
  77. : "i" (offsetof(PAL_TCB_URTS, self)));
  78. return tcb;
  79. }
  80. # endif
  81. #endif /* __SGX_TLS_H__ */