tz_system.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. #include <linux/module.h>
  2. #include <linux/types.h>
  3. #include <linux/mm.h>
  4. #include <linux/slab.h>
  5. #include <linux/delay.h>
  6. #include <linux/kthread.h>
  7. #include <linux/uaccess.h>
  8. #include "tz_cross/trustzone.h"
  9. #include "tz_cross/ta_system.h"
  10. #include "trustzone/kree/system.h"
  11. #include "kree_int.h"
  12. #include "sys_ipc.h"
  13. #include "kree/tz_trusty.h"
  14. #ifdef CONFIG_ARM64
  15. #define ARM_SMC_CALLING_CONVENTION
  16. #endif
  17. #ifndef CONFIG_TRUSTY
  18. static TZ_RESULT KREE_ServPuts(u32 op, u8 param[REE_SERVICE_BUFFER_SIZE]);
  19. static TZ_RESULT KREE_ServUSleep(u32 op, u8 param[REE_SERVICE_BUFFER_SIZE]);
  20. static TZ_RESULT tz_ree_service(u32 op, u8 param[REE_SERVICE_BUFFER_SIZE]);
  21. static TZ_RESULT KREE_ServThread_Create(u32 op,
  22. u8 uparam[REE_SERVICE_BUFFER_SIZE]);
  23. static const KREE_REE_Service_Func ree_service_funcs[] = {
  24. 0,
  25. KREE_ServPuts,
  26. KREE_ServUSleep,
  27. KREE_ServMutexCreate,
  28. KREE_ServMutexDestroy,
  29. KREE_ServMutexLock,
  30. KREE_ServMutexUnlock,
  31. KREE_ServMutexTrylock,
  32. KREE_ServMutexIslock,
  33. KREE_ServSemaphoreCreate,
  34. KREE_ServSemaphoreDestroy,
  35. KREE_ServSemaphoreDown,
  36. KREE_ServSemaphoreDownTimeout,
  37. KREE_ServSemaphoreDowntrylock,
  38. KREE_ServSemaphoreUp,
  39. #if 0
  40. KREE_ServWaitqCreate,
  41. KREE_ServWaitqDestroy,
  42. KREE_ServWaitqWaitevent,
  43. KREE_ServWaitqWaiteventTimeout,
  44. KREE_ServWaitqWakeup,
  45. #endif
  46. KREE_ServRequestIrq,
  47. KREE_ServEnableIrq,
  48. KREE_ServEnableClock,
  49. KREE_ServDisableClock,
  50. KREE_ServThread_Create,
  51. KREE_ServSemaphoreDownInterruptible,
  52. };
  53. #define ree_service_funcs_num \
  54. (sizeof(ree_service_funcs)/sizeof(ree_service_funcs[0]))
  55. #endif
  56. #if defined(ARM_SMC_CALLING_CONVENTION)
  57. #define SMC_UNK 0xffffffff
  58. #ifdef CONFIG_TRUSTY
  59. struct smc_args_s {
  60. void *param;
  61. void *reebuf;
  62. uint32_t handle;
  63. uint32_t command;
  64. uint32_t paramTypes;
  65. };
  66. #define SMC_MTEE_SERVICE_CALL (0x34000008)
  67. static u32 tz_service_call(struct smc_args_s *smc_arg)
  68. {
  69. s32 ret;
  70. u64 param[REE_SERVICE_BUFFER_SIZE / sizeof(u64)];
  71. smc_arg->reebuf = param;
  72. ret = trusty_mtee_std_call32(SMC_MTEE_SERVICE_CALL,
  73. (u32)(u64)smc_arg,
  74. (u32)((u64)smc_arg >> 32),
  75. (u32)(u64)param);
  76. return ret;
  77. }
  78. TZ_RESULT KREE_TeeServiceCallNoCheck(KREE_SESSION_HANDLE handle,
  79. uint32_t command, uint32_t paramTypes,
  80. MTEEC_PARAM param[4])
  81. {
  82. struct smc_args_s smc_arg = { .param = param,
  83. .handle = handle,
  84. .command = command,
  85. .paramTypes = paramTypes };
  86. return (TZ_RESULT) tz_service_call(&smc_arg);
  87. }
  88. #else /* ~CONFIG_TRUSTY */
  89. #define SMC_MTEE_SERVICE_CALL (0x32000008)
  90. static u32 tz_service_call(u32 handle, u32 op, u32 arg1, unsigned long arg2)
  91. {
  92. #ifdef CONFIG_ARM64
  93. u64 param[REE_SERVICE_BUFFER_SIZE / sizeof(u64)];
  94. register u64 x0 asm("x0") = SMC_MTEE_SERVICE_CALL;
  95. register u64 x1 asm("x1") = handle;
  96. register u64 x2 asm("x2") = op;
  97. register u64 x3 asm("x3") = arg1;
  98. register u64 x4 asm("x4") = arg2;
  99. register u64 x5 asm("x5") = (unsigned long)param;
  100. asm volatile (
  101. __asmeq("%0", "x0")
  102. __asmeq("%1", "x1")
  103. __asmeq("%2", "x2")
  104. __asmeq("%3", "x3")
  105. __asmeq("%4", "x0")
  106. __asmeq("%5", "x1")
  107. __asmeq("%6", "x2")
  108. __asmeq("%7", "x3")
  109. __asmeq("%8", "x4")
  110. __asmeq("%9", "x5")
  111. "smc #0\n" :
  112. "=r"(x0), "=r"(x1), "=r"(x2), "=r" (x3) :
  113. "r"(x0), "r"(x1), "r"(x2), "r" (x3), "r"(x4), "r"(x5) :
  114. "memory");
  115. while (x1 != 0 && x0 != SMC_UNK) {
  116. /* Need REE service */
  117. /* r0 is the command, parameter in param buffer */
  118. x1 = tz_ree_service(x2, (u8 *) param);
  119. /* Work complete. Going Back to TZ again */
  120. x0 = SMC_MTEE_SERVICE_CALL;
  121. asm volatile (
  122. __asmeq("%0", "x0")
  123. __asmeq("%1", "x1")
  124. __asmeq("%2", "x2")
  125. __asmeq("%3", "x3")
  126. __asmeq("%4", "x0")
  127. __asmeq("%5", "x1")
  128. __asmeq("%6", "x2")
  129. __asmeq("%7", "x3")
  130. "smc #0\n" :
  131. "=r"(x0), "=r"(x1), "=r"(x2), "=r"(x3) :
  132. "r"(x0), "r"(x1), "r"(x2), "r"(x3) :
  133. "memory");
  134. }
  135. return x3;
  136. #else
  137. u32 param[REE_SERVICE_BUFFER_SIZE / sizeof(u32)];
  138. register u32 r0 asm("x0") = SMC_MTEE_SERVICE_CALL;
  139. register u32 r1 asm("x1") = handle;
  140. register u32 r2 asm("x2") = op;
  141. register u32 r3 asm("x3") = arg1;
  142. register u32 r4 asm("x4") = arg2;
  143. register u32 r5 asm("x5") = (unsigned long)param;
  144. asm volatile (".arch_extension sec\n"
  145. __asmeq("%0", "r0")
  146. __asmeq("%1", "r1")
  147. __asmeq("%2", "r2")
  148. __asmeq("%3", "r0")
  149. __asmeq("%4", "r1")
  150. __asmeq("%5", "r2")
  151. __asmeq("%6", "r3")
  152. __asmeq("%7", "r4")
  153. __asmeq("%8", "r5")
  154. "smc #0\n" :
  155. "=r"(r0), "=r"(r1), "=r"(r2) :
  156. "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5) :
  157. "memory");
  158. while (r1 != 0) {
  159. /* Need REE service */
  160. /* r0 is the command, parameter in param buffer */
  161. r1 = tz_ree_service(r0, (u8 *) param);
  162. /* Work complete. Going Back to TZ again */
  163. r0 = 0x32003000;
  164. asm volatile (".arch_extension sec\n"
  165. __asmeq("%0", "r0")
  166. __asmeq("%1", "r1")
  167. __asmeq("%2", "r2")
  168. __asmeq("%3", "r0")
  169. __asmeq("%4", "r1")
  170. __asmeq("%5", "r5")
  171. "smc #0\n" :
  172. "=r"(r0), "=r"(r1), "=r"(r2) :
  173. "r"(r0), "r"(r1), "r"(r5) :
  174. "memory");
  175. }
  176. return r2;
  177. #endif
  178. }
  179. TZ_RESULT KREE_TeeServiceCallNoCheck(KREE_SESSION_HANDLE handle,
  180. uint32_t command, uint32_t paramTypes,
  181. MTEEC_PARAM param[4])
  182. {
  183. return (TZ_RESULT) tz_service_call(handle, command, paramTypes,
  184. (unsigned long) param);
  185. }
  186. #endif /* CONFIG_TRUSTY */
  187. #else
  188. static u32 tz_service_call(u32 handle, u32 op, u32 arg1, u32 arg2)
  189. {
  190. /* Reserve buffer for REE service call parameters */
  191. u32 param[REE_SERVICE_BUFFER_SIZE / sizeof(u32)];
  192. register u32 r0 asm("r0") = handle;
  193. register u32 r1 asm("r1") = op;
  194. register u32 r2 asm("r2") = arg1;
  195. register u32 r3 asm("r3") = arg2;
  196. register u32 r4 asm("r4") = (u32) param;
  197. asm volatile (".arch_extension sec\n"
  198. __asmeq("%0", "r0")
  199. __asmeq("%1", "r1")
  200. __asmeq("%2", "r0")
  201. __asmeq("%3", "r1")
  202. __asmeq("%4", "r2")
  203. __asmeq("%5", "r3")
  204. __asmeq("%6", "r4")
  205. "smc #0\n" :
  206. "=r"(r0), "=r"(r1) :
  207. "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4) :
  208. "memory");
  209. while (r1 != 0) {
  210. /* Need REE service */
  211. /* r0 is the command, parameter in param buffer */
  212. r1 = tz_ree_service(r0, (u8 *) param);
  213. /* Work complete. Going Back to TZ again */
  214. r0 = 0xffffffff;
  215. asm volatile (".arch_extension sec\n"
  216. __asmeq("%0", "r0")
  217. __asmeq("%1", "r1")
  218. __asmeq("%2", "r0")
  219. __asmeq("%3", "r1")
  220. __asmeq("%4", "r4")
  221. "smc #0\n" :
  222. "=r"(r0), "=r"(r1) :
  223. "r"(r0), "r"(r1), "r"(r4) :
  224. "memory");
  225. }
  226. return r0;
  227. }
  228. TZ_RESULT KREE_TeeServiceCallNoCheck(KREE_SESSION_HANDLE handle,
  229. uint32_t command, uint32_t paramTypes,
  230. MTEEC_PARAM param[4])
  231. {
  232. return (TZ_RESULT) tz_service_call(handle, command, paramTypes,
  233. (u32) param);
  234. }
  235. #endif
  236. TZ_RESULT KREE_TeeServiceCall(KREE_SESSION_HANDLE handle, uint32_t command,
  237. uint32_t paramTypes, MTEEC_PARAM oparam[4])
  238. {
  239. int i, do_copy = 0;
  240. TZ_RESULT ret;
  241. uint32_t tmpTypes;
  242. MTEEC_PARAM param[4];
  243. /* Parameter processing. */
  244. memset(param, 0, sizeof(param));
  245. tmpTypes = paramTypes;
  246. for (i = 0; tmpTypes; i++) {
  247. TZ_PARAM_TYPES type = tmpTypes & 0xff;
  248. tmpTypes >>= 8;
  249. switch (type) {
  250. case TZPT_VALUE_INPUT:
  251. case TZPT_VALUE_INOUT:
  252. case TZPT_VALUE_OUTPUT:
  253. param[i] = oparam[i];
  254. break;
  255. case TZPT_MEM_INPUT:
  256. case TZPT_MEM_OUTPUT:
  257. case TZPT_MEM_INOUT:
  258. /* Check if point to kernel low memory */
  259. param[i] = oparam[i];
  260. if (param[i].mem.buffer < (void *)PAGE_OFFSET ||
  261. param[i].mem.buffer >= high_memory) {
  262. /* No, we need to copy.... */
  263. if (param[i].mem.size > TEE_PARAM_MEM_LIMIT) {
  264. param[i].mem.buffer = 0;
  265. ret = TZ_RESULT_ERROR_OUT_OF_MEMORY;
  266. goto error;
  267. }
  268. param[i].mem.buffer = kmalloc(
  269. param[i].mem.size, GFP_KERNEL);
  270. if (!param[i].mem.buffer) {
  271. ret = TZ_RESULT_ERROR_OUT_OF_MEMORY;
  272. goto error;
  273. }
  274. memcpy(param[i].mem.buffer,
  275. oparam[i].mem.buffer,
  276. param[i].mem.size);
  277. }
  278. break;
  279. case TZPT_MEMREF_INPUT:
  280. case TZPT_MEMREF_OUTPUT:
  281. case TZPT_MEMREF_INOUT:
  282. /* Check if share memory is valid. */
  283. /* Not done yet. */
  284. param[i] = oparam[i];
  285. break;
  286. default:
  287. /* Bad format, return. */
  288. return TZ_RESULT_ERROR_BAD_FORMAT;
  289. }
  290. }
  291. /* Real call. */
  292. do_copy = 1;
  293. ret = KREE_TeeServiceCallNoCheck(handle, command, paramTypes, param);
  294. error:
  295. tmpTypes = paramTypes;
  296. for (i = 0; tmpTypes; i++) {
  297. TZ_PARAM_TYPES type = tmpTypes & 0xff;
  298. tmpTypes >>= 8;
  299. switch (type) {
  300. case TZPT_VALUE_INOUT:
  301. case TZPT_VALUE_OUTPUT:
  302. oparam[i] = param[i];
  303. break;
  304. case TZPT_MEM_INPUT:
  305. case TZPT_MEM_OUTPUT:
  306. case TZPT_MEM_INOUT:
  307. /* Check if point to kernel memory */
  308. if (param[i].mem.buffer &&
  309. (param[i].mem.buffer != oparam[i].mem.buffer)) {
  310. if (type != TZPT_MEM_INPUT && do_copy)
  311. memcpy(oparam[i].mem.buffer,
  312. param[i].mem.buffer,
  313. param[i].mem.size);
  314. kfree(param[i].mem.buffer);
  315. }
  316. break;
  317. case TZPT_MEMREF_INPUT:
  318. case TZPT_MEMREF_OUTPUT:
  319. case TZPT_MEMREF_INOUT:
  320. case TZPT_VALUE_INPUT:
  321. default:
  322. /* Nothing to do */
  323. break;
  324. }
  325. }
  326. return ret;
  327. }
  328. EXPORT_SYMBOL(KREE_TeeServiceCall);
  329. #ifndef CONFIG_TRUSTY
  330. static TZ_RESULT KREE_ServPuts(u32 op, u8 param[REE_SERVICE_BUFFER_SIZE])
  331. {
  332. param[REE_SERVICE_BUFFER_SIZE - 1] = 0;
  333. pr_warn("%s", param);
  334. return TZ_RESULT_SUCCESS;
  335. }
  336. static TZ_RESULT KREE_ServUSleep(u32 op, u8 uparam[REE_SERVICE_BUFFER_SIZE])
  337. {
  338. struct ree_service_usleep *param = (struct ree_service_usleep *)uparam;
  339. usleep_range(param->ustime-1, param->ustime);
  340. return TZ_RESULT_SUCCESS;
  341. }
  342. /* TEE Kthread create by REE service, TEE service call body
  343. */
  344. static int kree_thread_function(void *arg)
  345. {
  346. MTEEC_PARAM param[4];
  347. uint32_t paramTypes;
  348. int ret;
  349. struct REE_THREAD_INFO *info = (struct REE_THREAD_INFO *)arg;
  350. paramTypes = TZ_ParamTypes2(TZPT_VALUE_INPUT, TZPT_VALUE_OUTPUT);
  351. param[0].value.a = (uint32_t) info->handle;
  352. /* free parameter resource */
  353. kfree(info);
  354. /* create TEE kthread */
  355. ret = KREE_TeeServiceCall(
  356. (KREE_SESSION_HANDLE) MTEE_SESSION_HANDLE_SYSTEM,
  357. TZCMD_SYS_THREAD_CREATE, paramTypes, param);
  358. return ret;
  359. }
  360. /* TEE Kthread create by REE service
  361. */
  362. static TZ_RESULT KREE_ServThread_Create(u32 op,
  363. u8 uparam[REE_SERVICE_BUFFER_SIZE])
  364. {
  365. struct REE_THREAD_INFO *info;
  366. /* get parameters */
  367. /* the resource will be freed after the thread stops */
  368. info = kmalloc(sizeof(struct REE_THREAD_INFO), GFP_KERNEL);
  369. if (info == NULL)
  370. return TZ_RESULT_ERROR_OUT_OF_MEMORY;
  371. memcpy(info, uparam, sizeof(struct REE_THREAD_INFO));
  372. /* create thread and run ... */
  373. if (!kthread_run(kree_thread_function, info, info->name))
  374. return TZ_RESULT_ERROR_GENERIC;
  375. return TZ_RESULT_SUCCESS;
  376. }
  377. static TZ_RESULT tz_ree_service(u32 op, u8 param[REE_SERVICE_BUFFER_SIZE])
  378. {
  379. KREE_REE_Service_Func func;
  380. if (op >= ree_service_funcs_num)
  381. return TZ_RESULT_ERROR_BAD_PARAMETERS;
  382. func = ree_service_funcs[op];
  383. if (!func)
  384. return TZ_RESULT_ERROR_BAD_PARAMETERS;
  385. return (func) (op, param);
  386. }
  387. #endif /* ~CONFIG_TRUSTY */
  388. TZ_RESULT KREE_InitTZ(void)
  389. {
  390. uint32_t paramTypes;
  391. MTEEC_PARAM param[4];
  392. TZ_RESULT ret;
  393. paramTypes = TZPT_NONE;
  394. ret = KREE_TeeServiceCall(
  395. (KREE_SESSION_HANDLE) MTEE_SESSION_HANDLE_SYSTEM,
  396. TZCMD_SYS_INIT, paramTypes, param);
  397. return ret;
  398. }
  399. TZ_RESULT KREE_CreateSession(const char *ta_uuid, KREE_SESSION_HANDLE *pHandle)
  400. {
  401. uint32_t paramTypes;
  402. MTEEC_PARAM param[4];
  403. TZ_RESULT ret;
  404. if (!ta_uuid || !pHandle)
  405. return TZ_RESULT_ERROR_BAD_PARAMETERS;
  406. param[0].mem.buffer = (char *)ta_uuid;
  407. param[0].mem.size = strlen(ta_uuid) + 1;
  408. paramTypes = TZ_ParamTypes2(TZPT_MEM_INPUT, TZPT_VALUE_OUTPUT);
  409. ret = KREE_TeeServiceCall(
  410. (KREE_SESSION_HANDLE) MTEE_SESSION_HANDLE_SYSTEM,
  411. TZCMD_SYS_SESSION_CREATE, paramTypes, param);
  412. if (ret == TZ_RESULT_SUCCESS)
  413. *pHandle = (KREE_SESSION_HANDLE)param[1].value.a;
  414. return ret;
  415. }
  416. EXPORT_SYMBOL(KREE_CreateSession);
  417. TZ_RESULT KREE_CloseSession(KREE_SESSION_HANDLE handle)
  418. {
  419. uint32_t paramTypes;
  420. MTEEC_PARAM param[4];
  421. TZ_RESULT ret;
  422. param[0].value.a = (uint32_t) handle;
  423. paramTypes = TZ_ParamTypes1(TZPT_VALUE_INPUT);
  424. ret = KREE_TeeServiceCall(
  425. (KREE_SESSION_HANDLE) MTEE_SESSION_HANDLE_SYSTEM,
  426. TZCMD_SYS_SESSION_CLOSE, paramTypes, param);
  427. return ret;
  428. }
  429. EXPORT_SYMBOL(KREE_CloseSession);
  430. #include "tz_cross/tz_error_strings.h"
  431. const char *TZ_GetErrorString(TZ_RESULT res)
  432. {
  433. return _TZ_GetErrorString(res);
  434. }
  435. EXPORT_SYMBOL(TZ_GetErrorString);