sgx_tls.h 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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. void* ecall_return_addr;
  18. void* ssa;
  19. sgx_pal_gpr_t* gpr;
  20. void* exit_target;
  21. void* fsbase;
  22. void* stack;
  23. void* ustack_top;
  24. void* ustack;
  25. struct pal_handle_thread* thread;
  26. uint64_t ocall_prepared;
  27. uint64_t thread_started;
  28. uint64_t ready_for_exceptions;
  29. uint64_t manifest_size;
  30. void* heap_min;
  31. void* heap_max;
  32. void* exec_addr;
  33. uint64_t exec_size;
  34. int* clear_child_tid;
  35. };
  36. };
  37. typedef struct pal_tcb_linux {
  38. PAL_TCB common;
  39. struct {
  40. /* private to untrusted Linux PAL, unique to each untrusted thread */
  41. sgx_arch_tcs_t* tcs; /* TCS page of SGX corresponding to thread, for EENTER */
  42. void* stack; /* bottom of stack, for later freeing when thread exits */
  43. void* alt_stack; /* bottom of alt stack, for child thread to init alt stack */
  44. };
  45. } PAL_TCB_LINUX;
  46. static inline PAL_TCB_LINUX* get_tcb_linux(void) {
  47. return (PAL_TCB_LINUX*)pal_get_tcb();
  48. }
  49. #ifndef DEBUG
  50. extern uint64_t dummy_debug_variable;
  51. #endif
  52. # ifdef IN_ENCLAVE
  53. # define GET_ENCLAVE_TLS(member) \
  54. ({ \
  55. struct enclave_tls * tmp; \
  56. uint64_t val; \
  57. static_assert(sizeof(tmp->member) == 8, \
  58. "sgx_tls member should have 8-byte type"); \
  59. __asm__ ("movq %%gs:%c1, %q0": "=r" (val) \
  60. : "i" (offsetof(struct enclave_tls, member))); \
  61. (__typeof(tmp->member)) val; \
  62. })
  63. # define SET_ENCLAVE_TLS(member, value) \
  64. do { \
  65. struct enclave_tls * tmp; \
  66. static_assert(sizeof(tmp->member) == 8, \
  67. "sgx_tls member should have 8-byte type"); \
  68. static_assert(sizeof(value) == 8, \
  69. "only 8-byte type can be set to sgx_tls"); \
  70. __asm__ ("movq %q0, %%gs:%c1":: "r" (value), \
  71. "i" (offsetof(struct enclave_tls, member))); \
  72. } while (0)
  73. # endif
  74. #endif /* __SGX_TLS_H__ */