sgx_thread.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
  2. /* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
  3. #include "pal_internal.h"
  4. #include "sgx_internal.h"
  5. #include "pal_security.h"
  6. #include <pthread.h>
  7. #include <linux/futex.h>
  8. #include <asm/signal.h>
  9. #include <asm/prctl.h>
  10. #include "sgx_enclave.h"
  11. #include "debugger/sgx_gdb.h"
  12. __thread struct pal_enclave * current_enclave;
  13. __thread sgx_arch_tcs_t * current_tcs;
  14. struct thread_map {
  15. unsigned int tid;
  16. sgx_arch_tcs_t * tcs;
  17. };
  18. static sgx_arch_tcs_t * enclave_tcs;
  19. static int enclave_thread_num;
  20. static struct thread_map * enclave_thread_map;
  21. void create_tcs_mapper (void * tcs_base, unsigned int thread_num)
  22. {
  23. enclave_tcs = tcs_base;
  24. enclave_thread_map = malloc(sizeof(struct thread_map) * thread_num);
  25. enclave_thread_num = thread_num;
  26. for (int i = 0 ; i < thread_num ; i++) {
  27. enclave_thread_map[i].tid = 0;
  28. enclave_thread_map[i].tcs = &enclave_tcs[i];
  29. }
  30. }
  31. void map_tcs (unsigned int tid)
  32. {
  33. for (int i = 0 ; i < enclave_thread_num ; i++)
  34. if (!enclave_thread_map[i].tid) {
  35. enclave_thread_map[i].tid = tid;
  36. current_tcs = enclave_thread_map[i].tcs;
  37. ((struct enclave_dbginfo *) DBGINFO_ADDR)->thread_tids[i] = tid;
  38. break;
  39. }
  40. }
  41. void unmap_tcs (void)
  42. {
  43. int index = current_tcs - enclave_tcs;
  44. struct thread_map * map = &enclave_thread_map[index];
  45. if (index >= enclave_thread_num)
  46. return;
  47. SGX_DBG(DBG_I, "unmap TCS at 0x%08lx\n", map->tcs);
  48. current_tcs = NULL;
  49. ((struct enclave_dbginfo *) DBGINFO_ADDR)->thread_tids[index] = 0;
  50. map->tid = 0;
  51. map->tcs = NULL;
  52. }
  53. static void * thread_start (void * arg)
  54. {
  55. int tid = INLINE_SYSCALL(gettid, 0);
  56. map_tcs(tid);
  57. current_enclave = arg;
  58. if (!current_tcs) {
  59. SGX_DBG(DBG_E, "Cannot attach to any TCS!\n");
  60. return NULL;
  61. }
  62. ecall_thread_start();
  63. unmap_tcs();
  64. return NULL;
  65. }
  66. int clone_thread (void)
  67. {
  68. pthread_t thread;
  69. return pthread_create(&thread, NULL, thread_start, current_enclave);
  70. }
  71. int interrupt_thread (void * tcs)
  72. {
  73. int index = (sgx_arch_tcs_t *) tcs - enclave_tcs;
  74. struct thread_map * map = &enclave_thread_map[index];
  75. if (index >= enclave_thread_num)
  76. return -PAL_ERROR_INVAL;
  77. if (!map->tid)
  78. return -PAL_ERROR_INVAL;
  79. INLINE_SYSCALL(tgkill, 3, PAL_SEC()->pid, map->tid, SIGCONT);
  80. return 0;
  81. }