sgx_tls.h 3.4 KB

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