1 /*
2 * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3 * Licensed under the Mulan PSL v2.
4 * You can use this software according to the terms and conditions of the Mulan PSL v2.
5 * You may obtain a copy of Mulan PSL v2 at:
6 * http://license.coscl.org.cn/MulanPSL2
7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9 * PURPOSE.
10 * See the Mulan PSL v2 for more details.
11 */
12
13 #include <stddef.h>
14 #include <dlist.h>
15 #include "tee_log.h"
16 #include "tee_mem_mgmt_api.h"
17 #include "ta_framework.h"
18 #include "gtask_inner.h"
19 #include "session_manager.h"
20 #include "service_manager.h"
21 #include "agent_manager.h"
22 #include "mem_manager.h"
23 #include "tee_ext_api.h"
24 #include "tee_config.h"
25 #include "gtask_config_hal.h"
26 #include "securec.h"
27
28 #include "gtask_adapt.h"
29 #include "dynload.h"
30 #include "task_adaptor_pub.h"
31 #include "tee_task.h"
32 #include "tee_task_exception.h"
33 #include <ipclib_hal.h>
34
35 #define DEFAULT_EVENT_NR 0xffffffff
36
37 struct service_struct *g_cur_service = (struct service_struct *)NULL;
38 struct session_struct *g_cur_session = (struct session_struct *)NULL;
39
40 /* static funs declare */
41 int32_t find_service(const TEE_UUID *uuid, uint32_t service_index, struct service_struct **entry);
42 void set_session_context(smc_cmd_t *cmd, uint32_t service_index, uint32_t session_id);
43 TEE_Result process_close_session_entry(struct service_struct **service, struct session_struct **session);
44 void process_close_ta2ta_target_sessions(uint32_t from_taskid, uint32_t level);
45
get_cur_session(void)46 struct session_struct *get_cur_session(void)
47 {
48 return g_cur_session;
49 }
50
get_cur_service(void)51 struct service_struct *get_cur_service(void)
52 {
53 return g_cur_service;
54 }
55
call_ta_invoke_close_session(const smc_cmd_t * cmd,uint32_t cmd_type,uint32_t cmd_id,global_to_ta_msg * entry_msg)56 static TEE_Result __attribute__((noinline)) call_ta_invoke_close_session(const smc_cmd_t *cmd, uint32_t cmd_type, uint32_t cmd_id,
57 global_to_ta_msg *entry_msg)
58 {
59 TEE_Result ret;
60
61 if (cmd->ret_val == TEE_PENDING2 || cmd->ret_val == TEE_PENDING)
62 return TEE_SUCCESS;
63
64 entry_msg->session_id = set_session_context_bit(g_cur_service->index, g_cur_session->session_id);
65 entry_msg->session_context = g_cur_session->session_context;
66 entry_msg->cmd_id = cmd->cmd_id;
67 entry_msg->dev_id = cmd->dev_file_id;
68 entry_msg->started = cmd->started;
69
70 if (cmd_id == CALL_TA_CLOSE_SESSION) {
71 if (g_cur_service->session_count == 1 && g_cur_service->property.keep_alive == false)
72 entry_msg->last_session = 1;
73 }
74 if (cmd_type == CMD_TYPE_NS_TO_SECURE) {
75 ret = cmd_ns_get_params(g_cur_session->task_id, cmd, &entry_msg->param_type, &entry_msg->params);
76 if (ret != TEE_SUCCESS) {
77 tloge("map ns params error\n");
78 return ret;
79 }
80 entry_msg->session_type = SESSION_FROM_CA;
81 } else {
82 ret = cmd_secure_get_params(g_cur_session->task_id, cmd, &entry_msg->param_type, &entry_msg->params);
83 if (ret != TEE_SUCCESS) {
84 tloge("map secure params error\n");
85 return ret;
86 }
87 entry_msg->session_type = SESSION_FROM_TA;
88 }
89
90 return ret;
91 }
92
set_init_msg_prop(const struct ta_property * in,ta_property_t_64 * out)93 static void set_init_msg_prop(const struct ta_property *in, ta_property_t_64 *out)
94 {
95 out->uuid = in->uuid;
96 out->stack_size = in->stack_size;
97 out->heap_size = in->heap_size;
98 out->single_instance = in->single_instance;
99 out->multi_session = in->multi_session;
100 out->keep_alive = in->keep_alive;
101 out->ssa_enum_enable = in->ssa_enum_enable;
102 out->other_buff = (uintptr_t)in->other_buff;
103 out->other_len = in->other_len;
104 }
105
check_and_process_init_build(ta_init_msg * init_msg,global_to_ta_msg * entry_msg,bool * flag)106 static TEE_Result check_and_process_init_build(ta_init_msg *init_msg,
107 global_to_ta_msg *entry_msg, bool *flag)
108 {
109 TEE_Result ret;
110
111 if (g_cur_service->init_build == 0) {
112 tlogd("Do service initial build!\n");
113 *flag = true;
114 /*
115 * Once the first msg CALL_TA_OPEN_SESSION_INIT send
116 * to TA, TA will do init work like clear bss etc,
117 * So we need make sure the other session of the TA will
118 * not send msg with init_build=0 again.
119 */
120 g_cur_service->init_build = 1;
121
122 set_init_msg_prop(&g_cur_service->property, &(init_msg->prop));
123 init_msg->login_method = g_cur_session->login_method;
124
125 ret = send_ta_init_msg(init_msg, g_cur_service->ta_64bit, CALL_TA_OPEN_SESSION_INIT,
126 g_cur_session->task_id);
127 if (ret != TEE_SUCCESS) {
128 tloge("send open session init msg to session[%s] failed:0x%x\n", g_cur_session->name, ret);
129 return ret;
130 }
131 g_cur_session->wait_ta_back_msg = true;
132
133 return TEE_SUCCESS;
134 }
135
136 if (g_cur_service->session_count == 1)
137 entry_msg->first_session = 1;
138
139 return TEE_SUCCESS;
140 }
141
async_call_ta_entry(const smc_cmd_t * cmd,uint32_t cmd_type,uint32_t cmd_id)142 TEE_Result async_call_ta_entry(const smc_cmd_t *cmd, uint32_t cmd_type, uint32_t cmd_id)
143 {
144 global_to_ta_msg entry_msg = { 0 };
145 ta_init_msg init_msg = { 0 };
146 TEE_Result ret;
147 bool flag = false;
148
149 if (cmd == NULL || g_cur_session == NULL)
150 return TEE_ERROR_BAD_PARAMETERS;
151
152 /*
153 * If the TA has agent pending command but the incomming command
154 * does not come from the agent then we cannot forward the command
155 * because the TA is single threaded!
156 */
157 if (g_cur_session->agent_pending) {
158 tloge("session %s is busy, command %u rejected\n", g_cur_session->name, cmd_id);
159 return TEE_ERROR_BUSY;
160 }
161
162 g_cur_session->login_method = cmd->login_method;
163
164 switch (cmd_id) {
165 case CALL_TA_OPEN_SESSION:
166 ret = check_and_process_init_build(&init_msg, &entry_msg, &flag);
167 if (flag)
168 return ret;
169 /* fall-through */
170 case CALL_TA_INVOKE_CMD:
171 case CALL_TA_CLOSE_SESSION:
172 ret = call_ta_invoke_close_session(cmd, cmd_type, cmd_id, &entry_msg);
173 if (ret) {
174 tloge("call ta invoke_cmd or close_session error\n");
175 return ret;
176 }
177 break;
178 default:
179 tloge("invalid asyn cmd id %u\n", cmd_id);
180 return TEE_ERROR_GENERIC;
181 }
182
183 tlogd("send to TA(0x%x): cmd=0x%x, session_id=0x%x\n", g_cur_session->task_id, cmd_id, entry_msg.session_id);
184 ret = send_global2ta_msg(&entry_msg, cmd_id, g_cur_session->task_id, NULL);
185 if (ret != TEE_SUCCESS) {
186 tloge("msg send to ta failed:0x%x\n", ret);
187 return ret;
188 }
189
190 g_cur_session->wait_ta_back_msg = true;
191 return TEE_SUCCESS;
192 }
193
session_set_cancelable(bool cancelable)194 void session_set_cancelable(bool cancelable)
195 {
196 if (g_cur_session != NULL)
197 g_cur_session->cancelable = cancelable;
198 }
199
find_session_with_dev_file_id(uint32_t session_id,uint32_t dev_file_id,const struct service_struct * srv)200 struct session_struct *find_session_with_dev_file_id(uint32_t session_id, uint32_t dev_file_id,
201 const struct service_struct *srv)
202 {
203 struct session_struct *sess_context = NULL;
204
205 if (srv == NULL)
206 return NULL;
207
208 dlist_for_each_entry (sess_context, &srv->session_head, struct session_struct, session_list) {
209 if ((sess_context->session_id == session_id) && (sess_context->cmd_in.dev_file_id == dev_file_id))
210 return sess_context;
211 }
212 return NULL;
213 }
214
reset_ta_context(void)215 void reset_ta_context(void)
216 {
217 g_cur_service = (struct service_struct *)NULL;
218 g_cur_session = (struct session_struct *)NULL;
219 }
220
set_tee_return_origin(smc_cmd_t * cmd,TEE_Result ret_origin)221 void set_tee_return_origin(smc_cmd_t *cmd, TEE_Result ret_origin)
222 {
223 if (cmd == NULL)
224 return;
225
226 cmd->err_origin = ret_origin;
227 }
228
set_tee_return(smc_cmd_t * cmd,TEE_Result ret_val)229 void set_tee_return(smc_cmd_t *cmd, TEE_Result ret_val)
230 {
231 if (cmd == NULL)
232 return;
233
234 cmd->ret_val = ret_val;
235 }
236
init_ta_service_session(const smc_cmd_t * cmd)237 static TEE_Result init_ta_service_session(const smc_cmd_t *cmd)
238 {
239 const TEE_UUID *uuid = NULL;
240 int32_t service_index;
241
242 uuid = (const TEE_UUID *)(uintptr_t)cmd->uuid;
243
244 if ((service_index = find_service(uuid, service_index_of_context(cmd->context), &g_cur_service)) == -1) {
245 tloge("service not found uuid = %x-%x\n", uuid->timeLow, uuid->timeMid);
246 return TEE_ERROR_SERVICE_NOT_EXIST;
247 }
248
249 g_cur_session = find_session_with_dev_file_id(session_id_of_context(cmd->context), cmd->dev_file_id, g_cur_service);
250 if ((g_cur_session == NULL) && (cmd->cmd_type != CMD_TYPE_GLOBAL)) {
251 tloge("session[%u] not exist in service[%s]\n", session_id_of_context(cmd->context), g_cur_service->name);
252 return TEE_ERROR_SESSION_NOT_EXIST;
253 }
254
255 return TEE_SUCCESS;
256 }
257
init_ta_context(const smc_cmd_t * cmd)258 TEE_Result init_ta_context(const smc_cmd_t *cmd)
259 {
260 if (cmd == NULL)
261 return TEE_ERROR_BAD_PARAMETERS;
262
263 TEE_Result ret = init_ta_service_session(cmd);
264 if (ret != 0) {
265 tloge("init ta service session error:%x\n", ret);
266 return ret;
267 }
268
269 return TEE_SUCCESS;
270 }
271
init_ta2ta_session(const smc_cmd_t * cmd)272 static TEE_Result init_ta2ta_session(const smc_cmd_t *cmd)
273 {
274 g_cur_session = find_session_with_dev_file_id(session_id_of_context(cmd->context), cmd->dev_file_id, g_cur_service);
275 if ((g_cur_session == NULL) && (cmd->cmd_type != CMD_TYPE_GLOBAL))
276 return TEE_ERROR_SESSION_NOT_EXIST;
277
278 return TEE_SUCCESS;
279 }
280
ta2ta_call_back(uint32_t task_id)281 static int ta2ta_call_back(uint32_t task_id)
282 {
283 struct service_struct *serv = NULL;
284 struct session_struct *sess = NULL;
285 uint32_t pre_task = task_id;
286 uint32_t level;
287
288 do {
289 if (!find_task(pre_task, &serv, &sess)) {
290 tloge("find service fail taskid:%u\n", pre_task);
291 return -1;
292 }
293
294 if (serv == g_cur_service) {
295 tloge("WRONG! ta2ta cannot call back\n");
296 return -1;
297 }
298 tlogd("sess level:%d\n", sess->ta2ta_level);
299
300 pre_task = sess->ta2ta_from_taskid;
301 level = sess->ta2ta_level;
302 } while (level > 0);
303
304 return 0;
305 }
306
307
check_ta2ta_context(uint32_t task_id)308 static TEE_Result check_ta2ta_context(uint32_t task_id)
309 {
310 /* check if there is a loop call */
311 if (ta2ta_call_back(task_id) != 0) {
312 tloge("ta2ta call in wrong state\n");
313 return TEE_ERROR_GENERIC;
314 }
315
316 /* We don't allow TA2TA session calls from TAs that did not initiate the session */
317 if (g_cur_session != NULL) {
318 if (g_cur_session->ta2ta_from_taskid != task_id) {
319 tloge("receive invalid ta2ta call from task 0x%x\n", task_id);
320 return TEE_ERROR_SESSION_NOT_EXIST;
321 }
322 }
323 return TEE_SUCCESS;
324 }
325
init_ta2ta_service(const smc_cmd_t * cmd)326 static TEE_Result init_ta2ta_service(const smc_cmd_t *cmd)
327 {
328 const TEE_UUID *uuid = NULL;
329
330 uuid = (const TEE_UUID *)(uintptr_t)cmd->uuid;
331 if (find_service(uuid, service_index_of_context(cmd->context), &g_cur_service) == -1) {
332 tloge("find second service fail\n");
333 return TEE_ERROR_SERVICE_NOT_EXIST;
334 }
335
336 return TEE_SUCCESS;
337 }
338
init_ta2ta_service_session(const smc_cmd_t * cmd)339 static TEE_Result init_ta2ta_service_session(const smc_cmd_t *cmd)
340 {
341 TEE_Result ret;
342 ret = init_ta2ta_service(cmd);
343 if (ret != TEE_SUCCESS) {
344 tloge("init ta2ta service error:%x\n", ret);
345 return ret;
346 }
347
348 ret = init_ta2ta_session(cmd);
349 if (ret != TEE_SUCCESS) {
350 tloge("init ta2ta session error:%x\n", ret);
351 return ret;
352 }
353
354 return ret;
355 }
356
init_ta2ta_agent_context(smc_cmd_t * cmd)357 TEE_Result init_ta2ta_agent_context(smc_cmd_t *cmd)
358 {
359 uint32_t ret_val;
360 TEE_Result ret;
361 struct service_struct *service = NULL;
362 struct session_struct *session = NULL;
363
364 if (cmd == NULL)
365 return TEE_ERROR_BAD_PARAMETERS;
366
367 ret_val = cmd->ret_val;
368
369 ret = init_ta2ta_service_session(cmd);
370 if (ret != TEE_SUCCESS)
371 return ret;
372
373 if ((g_cur_session != NULL) && (g_cur_session->cmd != NULL)) {
374 /* agent response will use a new cmd index, updata the event_nr in original cmd */
375 if (g_cur_session->cmd->event_nr != cmd->event_nr) {
376 /*
377 * The ta2ta cmd was already initialized so we need to change out cmd to point to the
378 * mapped pointer instead of the current cmd
379 */
380 if (!find_task(g_cur_session->ta2ta_from_taskid, &service, &session)) {
381 tloge("can't find session for ta2ta_from_taskid taskid=0x%x\n", g_cur_session->ta2ta_from_taskid);
382 return TEE_ERROR_GENERIC;
383 }
384
385 session->cmd_in.event_nr = cmd->event_nr;
386 session->cmd_in.ca_pid = cmd->ca_pid;
387 g_cur_session->cmd->event_nr = cmd->event_nr;
388 g_cur_session->cmd->ca_pid = cmd->ca_pid;
389 }
390 cmd = g_cur_session->cmd;
391 if (cmd != NULL) {
392 cmd->ret_val = ret_val;
393 } else {
394 /* this never happen */
395 tloge("out cmd is null\n");
396 return TEE_ERROR_GENERIC;
397 }
398 }
399
400 return TEE_SUCCESS;
401 }
402
init_ta2ta_context(smc_cmd_t * cmd,uint64_t ta_cmd,uint32_t task_id)403 TEE_Result init_ta2ta_context(smc_cmd_t *cmd, uint64_t ta_cmd, uint32_t task_id)
404 {
405 TEE_Result ret;
406 struct service_struct *service = NULL;
407 struct session_struct *session = NULL;
408
409 if (cmd == NULL || ta_cmd == 0)
410 return TEE_ERROR_BAD_PARAMETERS;
411
412 /* Need to remap the command id incomming from the secure ta2ta call */
413 if (map_secure_operation(ta_cmd, cmd, task_id) != TEE_SUCCESS)
414 return TEE_ERROR_OUT_OF_MEMORY;
415
416 if (!find_task(task_id, &service, &session)) {
417 tloge("can't find session for ta2ta call taskid=%u\n", task_id);
418 return TEE_ERROR_GENERIC;
419 }
420 /* TA2TA call will reuse the src TA's CA's cmd_index */
421 cmd->ca_pid = session->cmd_in.ca_pid;
422 cmd->event_nr = session->cmd_in.event_nr;
423 cmd->dev_file_id = session->cmd_in.dev_file_id;
424 tlogd("ta2ta call update, service_id=%u, session_id=%u, ca_pid=%u, event_nr=%u, dev_file_id=%u\n",
425 service->index, session->session_id, cmd->ca_pid, cmd->event_nr, cmd->dev_file_id);
426
427 ret = init_ta2ta_service_session(cmd);
428 if (ret != TEE_SUCCESS)
429 return ret;
430 ret = check_ta2ta_context(task_id);
431 if (ret != TEE_SUCCESS)
432 return ret;
433
434 /*
435 * If it's the first time we map the ta2ta command then set the internals of the session
436 * to point to it
437 */
438 if (g_cur_session != NULL) {
439 g_cur_session->cmd = &g_cur_session->cmd_in;
440 if (memcpy_s(&g_cur_session->cmd_in, sizeof(g_cur_session->cmd_in), cmd, sizeof(*cmd)) != TEE_SUCCESS) {
441 tloge("memcpy cmd_in failed\n");
442 return TEE_ERROR_GENERIC;
443 }
444 }
445
446 return TEE_SUCCESS;
447 }
448
init_session_context(uint32_t task_id,struct service_struct ** service,struct session_struct ** session)449 TEE_Result init_session_context(uint32_t task_id,
450 struct service_struct **service, struct session_struct **session)
451 {
452 if (!find_task(task_id, &g_cur_service, &g_cur_session))
453 return TEE_ERROR_SESSION_NOT_EXIST;
454
455 if (service != NULL)
456 *service = g_cur_service;
457 if (session != NULL)
458 *session = g_cur_session;
459
460 return TEE_SUCCESS;
461 }
462
set_session_context(smc_cmd_t * cmd,uint32_t service_index,uint32_t session_id)463 void set_session_context(smc_cmd_t *cmd, uint32_t service_index, uint32_t session_id)
464 {
465 if (cmd == NULL)
466 return;
467 cmd->context = set_session_context_bit(service_index, session_id);
468
469 tlogd("set session id = 0x%x\n", cmd->context);
470 }
471
get_session_id(void)472 int32_t get_session_id(void)
473 {
474 int32_t id = ERROR_SESSION_ID;
475 uint32_t i;
476
477 for (i = 0; i < MAX_SESSION_ID; i++) {
478 if ((g_cur_service->session_bitmap[get_index_by_uint32(i)] & (uint32_t)(0x1 << get_bit_by_uint32(i))) == 0) {
479 id = (int32_t)(i + 1);
480 break;
481 }
482 }
483
484 return id;
485 }
486
join_session_task_name(const char * service_name,struct session_struct * session)487 int join_session_task_name(const char *service_name, struct session_struct *session)
488 {
489 if (service_name == NULL || session == NULL)
490 return -1;
491
492 if (snprintf_s(session->name, SERVICE_NAME_MAX + SESSION_ID_LEN,
493 SERVICE_NAME_MAX + SESSION_ID_LEN - 1, "%u%s", session->session_id,
494 service_name) < 0) {
495 tloge("snprintf_s session name failed\n");
496 return -1;
497 }
498
499 return 0;
500 }
501
start_ta_task(const smc_cmd_t * cmd,uint32_t cmd_type)502 TEE_Result start_ta_task(const smc_cmd_t *cmd, uint32_t cmd_type)
503 {
504 TEE_Result ret;
505
506 if (cmd == NULL)
507 return TEE_ERROR_BAD_PARAMETERS;
508
509 if (g_cur_session != NULL &&
510 memcpy_s(&g_cur_session->cmd_in, sizeof(smc_cmd_t), cmd, sizeof(smc_cmd_t))) {
511 tloge("memcpy_s cmd_in failed\n");
512 return TEE_ERROR_GENERIC;
513 }
514
515 ret = async_call_ta_entry(cmd, cmd_type, CALL_TA_INVOKE_CMD);
516 return ret;
517 }
518
ta_task_init(struct tsk_init_param * task_param)519 static void ta_task_init(struct tsk_init_param *task_param)
520 {
521 if (task_param == NULL)
522 return;
523
524 task_param->task_prior = DEFAULT_TASK_PRIO;
525 task_param->task_name = g_cur_session->name;
526 task_param->que_num = DEFAULT_MSG_QUEUE_NUM;
527
528 task_param->uuid.timeLow = g_cur_service->property.uuid.timeLow;
529 task_param->uuid.timeMid = g_cur_service->property.uuid.timeMid;
530 task_param->uuid.timeHiAndVersion = g_cur_service->property.uuid.timeHiAndVersion;
531 int i;
532 for (i = 0; i < NODE_LEN; i++)
533 task_param->uuid.clockSeqAndNode[i] = g_cur_service->property.uuid.clockSeqAndNode[i];
534 }
535
get_ta2ta_level(uint32_t cmd_type,uint32_t task_id,uint32_t * level)536 static int get_ta2ta_level(uint32_t cmd_type, uint32_t task_id, uint32_t *level)
537 {
538 struct service_struct *serv = NULL;
539 struct session_struct *sess = NULL;
540
541 if (level == NULL) {
542 tloge("get ta2ta level invalid param\n");
543 return -1;
544 }
545
546 if (cmd_type == CMD_TYPE_NS_TO_SECURE) {
547 tlogd("type is ns to secure\n");
548 *level = 0;
549 return 0;
550 }
551
552 if (find_task(task_id, &serv, &sess) == 0) {
553 tloge("cannot find caller ta. something wrong\n");
554 return -1;
555 }
556
557 if (sess->ta2ta_level >= MAX_TA2TA_LEVEL) {
558 tloge("get caller ta2ta_level:%u, cannot open other ta\n", sess->ta2ta_level);
559 return -1;
560 }
561
562 *level = sess->ta2ta_level + 1;
563
564 return 0;
565 }
566
add_session_to_ta2ta_list(uint32_t cmd_type,uint32_t caller_task_id,struct session_struct * cur_sess)567 static void add_session_to_ta2ta_list(uint32_t cmd_type, uint32_t caller_task_id, struct session_struct *cur_sess)
568 {
569 struct service_struct *caller_serv = NULL;
570 struct session_struct *caller_sess = NULL;
571
572 if (cmd_type == CMD_TYPE_NS_TO_SECURE)
573 return;
574
575 if (find_task(caller_task_id, &caller_serv, &caller_sess) == 0) {
576 tloge("find caller task 0x%x failed\n", caller_task_id);
577 return;
578 }
579 dlist_insert_tail(&(cur_sess->child_ta_sess_list), &caller_sess->child_ta_sess_head);
580 }
581
release_srvc_gc(bool handle_ref_cnt,int sre_ret)582 static void release_srvc_gc(bool handle_ref_cnt, int sre_ret)
583 {
584 /*
585 * for built-in service, we only need to care about session node,
586 * don't need to care about service node
587 */
588 if (is_build_in_service(&(g_cur_service->property.uuid)))
589 return;
590
591 if (handle_ref_cnt)
592 decr_ref_cnt(g_cur_service);
593
594 /* when service thread is blocked and session count is 0, we release service thread */
595 if (sre_ret == TIMEOUT_FAIL_RET) {
596 tloge("%s is blocked and session count is %u\n",
597 g_cur_service->name, g_cur_service->session_count);
598 if (g_cur_service->session_count == 0) {
599 process_release_service(g_cur_service, TA_REGION_RELEASE);
600 g_cur_service = NULL;
601 }
602 return;
603 }
604
605 /*
606 * for non built-in TA, in following case, we release service node and service thread
607 * 1. keepalive is false;
608 * 2. keepalive is true, first open session;
609 */
610 if (g_cur_service->session_count == 0 && g_cur_service->ref_cnt == 0) {
611 bool need_release_service =
612 (!g_cur_service->property.keep_alive ||
613 (g_cur_service->property.keep_alive && g_cur_service->first_open));
614 if (need_release_service) {
615 process_release_service(g_cur_service, TA_REGION_RELEASE);
616 g_cur_service = NULL;
617 }
618 }
619 }
620
621 /* for normal TA and built-in TA, we need to release session node and service node. */
create_task_fail_gc(bool handle_ref_cnt,int sre_ret)622 static void create_task_fail_gc(bool handle_ref_cnt, int sre_ret)
623 {
624 if (g_cur_session != NULL) {
625 CLR_BIT(g_cur_service->session_bitmap[get_index_by_uint32(g_cur_session->session_id - 1)],
626 get_bit_by_uint32(g_cur_session->session_id - 1));
627 release_pam_node(g_cur_session->pam_node);
628 dlist_delete(&g_cur_session->session_list);
629 dlist_delete(&g_cur_session->child_ta_sess_list);
630 TEE_Free(g_cur_session);
631 g_cur_session = NULL;
632 }
633 release_srvc_gc(handle_ref_cnt, sre_ret);
634 }
635
open_session_fail_gc(void)636 static int open_session_fail_gc(void)
637 {
638 if (g_cur_service->session_count > 0) {
639 g_cur_service->session_count--;
640 uint32_t session_id = set_session_context_bit(g_cur_service->index, g_cur_session->session_id);
641 int32_t ret = sre_task_delete_ex(g_cur_session->task_id, false, session_id);
642 if (ret != SUCC_RET)
643 tloge("task del fail errorno =%d\n", ret);
644 return ret;
645 }
646 tloge("here session count never be 0, some bad things must happen\n");
647 return SUCC_RET;
648 }
649
add_new_session_into_list(struct session_struct ** session,uint32_t * session_id,uint32_t ta2ta_level)650 TEE_Result add_new_session_into_list(struct session_struct **session, uint32_t *session_id,
651 uint32_t ta2ta_level)
652 {
653 if (session == NULL || session_id == NULL || g_cur_service == NULL)
654 return TEE_ERROR_GENERIC;
655
656 /* session id will never be bigger than SESSION_MAX=8 */
657 int32_t tmp_id = get_session_id();
658 if (tmp_id == ERROR_SESSION_ID) {
659 tloge("failed to get session id, return TEE_ERROR_SESSION_MAXIMUM\n");
660 return TEE_ERROR_SESSION_MAXIMUM;
661 }
662 *session_id = (uint32_t)tmp_id;
663
664 *session = TEE_Malloc(sizeof(struct session_struct), 0);
665 if (*session == NULL)
666 return TEE_ERROR_OUT_OF_MEMORY;
667
668 (*session)->agent_pending = false;
669 (*session)->ta2ta_level = ta2ta_level;
670 (*session)->session_id = *session_id;
671
672 if (join_session_task_name(g_cur_service->name, *session) != 0) {
673 tloge("join session task name failed\n");
674 if (*session != NULL) {
675 TEE_Free(*session);
676 *session = NULL;
677 }
678 return TEE_ERROR_GENERIC;
679 }
680
681 dlist_init(&(*session)->session_list);
682 SET_BIT(g_cur_service->session_bitmap[get_index_by_uint32(*session_id - 1)],
683 get_bit_by_uint32(*session_id - 1));
684 dlist_insert_tail(&(*session)->session_list, &g_cur_service->session_head);
685 g_cur_session = *session;
686
687 /* Init list of locked agents */
688 dlist_init(&(*session)->locked_agents);
689 dlist_init(&(*session)->map_mem);
690
691 (*session)->session_status = TA_STATUS_NORMAL;
692 dlist_init(&(*session)->child_ta_sess_head);
693 dlist_init(&(*session)->child_ta_sess_list);
694
695 return TEE_SUCCESS;
696 }
697
create_session(smc_cmd_t * cmd,uint32_t cmd_type,uint32_t caller_id,bool handle_ref_cnt)698 static TEE_Result create_session(smc_cmd_t *cmd, uint32_t cmd_type, uint32_t caller_id, bool handle_ref_cnt)
699 {
700 TEE_Result ret = TEE_ERROR_GENERIC;
701 uint32_t task_id;
702 uint32_t session_id;
703 uint32_t level;
704 struct tsk_init_param task_init_param;
705 struct session_struct *session = NULL;
706
707 if (get_ta2ta_level(cmd_type, caller_id, &level) != 0)
708 goto generic_fail;
709
710 ret = add_new_session_into_list(&session, &session_id, level);
711 if (ret != TEE_SUCCESS)
712 goto generic_fail;
713
714 ta_task_init(&task_init_param);
715 int32_t sre_ret = sre_task_create(&task_init_param, &task_id);
716 if (sre_ret != 0) {
717 tloge("create task %s fail : errorno = 0x%x\n", g_cur_service->name, sre_ret);
718 ret = TEE_ERROR_GENERIC;
719 goto create_task_fail;
720 }
721 session->task_id = task_id;
722 session->ta2ta_from_taskid = caller_id;
723 add_session_to_ta2ta_list(cmd_type, caller_id, session);
724 session->wait_ta_back_msg = false;
725 set_session_context(cmd, g_cur_service->index, session_id);
726 g_cur_service->session_count++;
727 tlogd("create session-%d: %s: 0x%x\n", session_id, g_cur_service->name, task_id);
728 return ret;
729
730 create_task_fail:
731 create_task_fail_gc(handle_ref_cnt, sre_ret);
732 return ret;
733 generic_fail:
734 release_srvc_gc(handle_ref_cnt, SUCC_RET);
735 return ret;
736 }
737
check_session_accessible()738 static TEE_Result check_session_accessible()
739 {
740 if (is_system_service(g_cur_service)) {
741 tloge("session is denied\n");
742 return TEE_ERROR_ACCESS_DENIED;
743 }
744
745 if (g_cur_service->property.multi_session == false && g_cur_service->session_count > 0) {
746 struct session_struct *tmp_session =
747 dlist_entry(&(g_cur_service->session_head.next), struct session_struct, session_list);
748
749 if (true == tmp_session->cancelable) {
750 tloge("session[%s] is busy\n", tmp_session->name);
751 return TEE_ERROR_BUSY;
752 } else {
753 tloge("service[%s] only 1 session can be opened\n", g_cur_service->name);
754 return TEE_ERROR_ACCESS_CONFLICT;
755 }
756 }
757
758 return TEE_SUCCESS;
759 }
760
is_session_valid(const smc_cmd_t * cmd,uint32_t cmd_type)761 static TEE_Result is_session_valid(const smc_cmd_t *cmd, uint32_t cmd_type)
762 {
763 (void)cmd;
764 (void)cmd_type;
765
766 return check_session_accessible();
767 }
768
check_and_release_ta_elf(void)769 static void check_and_release_ta_elf(void)
770 {
771 if (!is_build_in_service(&(g_cur_service->property.uuid)) && g_cur_service->elf_state == ELF_EXIST) {
772 if (sre_release_dynamic_region(&g_cur_service->property.uuid, TA_REGION_RELEASE) != 0)
773 tloge("release elf failed\n");
774 }
775 }
776
do_resc_release_work(bool handle_ref_cnt)777 static void do_resc_release_work(bool handle_ref_cnt)
778 {
779 /* after session is created, elf and ref_cnt can be released. */
780 if (handle_ref_cnt) {
781 decr_ref_cnt(g_cur_service);
782 tlogd("service: %s, session count is %d ref_cnt-- is %d\n", g_cur_service->name, g_cur_service->session_count,
783 g_cur_service->ref_cnt);
784 }
785 check_and_release_ta_elf();
786 }
787
check_handle_ref_cnt(uint32_t cmd_type,const struct ta2ta_info_t * ta2ta_info)788 static bool check_handle_ref_cnt(uint32_t cmd_type, const struct ta2ta_info_t *ta2ta_info)
789 {
790 /*
791 * 1.ta2ta and ta elf is not loaded by secfile load agent
792 * 2.built-in service;
793 * don't need to handle ref_cnt
794 */
795 bool check_value = (cmd_type == CMD_TYPE_SECURE_TO_SECURE && ta2ta_info->is_load_worked == false) ||
796 is_build_in_service(&((g_cur_service->property).uuid));
797 if (check_value)
798 return false;
799 return true;
800 }
801
open_session(smc_cmd_t * cmd,uint32_t cmd_type,uint32_t caller_id,const struct ta2ta_info_t * ta2ta_info)802 TEE_Result open_session(smc_cmd_t *cmd, uint32_t cmd_type, uint32_t caller_id,
803 const struct ta2ta_info_t *ta2ta_info)
804 {
805 TEE_Result ret;
806 int sre_ret;
807
808 bool check_value = (g_cur_service == NULL || cmd == NULL);
809 if (check_value)
810 return TEE_ERROR_BAD_PARAMETERS;
811
812 check_value = (cmd_type == CMD_TYPE_SECURE_TO_SECURE && ta2ta_info == NULL);
813 if (check_value) {
814 tloge("ta2ta info is null, something bad must happened\n");
815 return TEE_ERROR_GENERIC;
816 }
817
818 bool handle_ref_cnt = check_handle_ref_cnt(cmd_type, ta2ta_info);
819
820 ret = is_session_valid(cmd, cmd_type);
821 if (ret != TEE_SUCCESS) {
822 create_task_fail_gc(handle_ref_cnt, SUCC_RET);
823 return ret;
824 }
825 ret = create_session(cmd, cmd_type, caller_id, handle_ref_cnt);
826 if (ret != TEE_SUCCESS) {
827 tloge("create session of service failed:0x%x\n", ret);
828 return ret;
829 }
830
831 g_cur_session->cmd_type = cmd_type;
832 if (memcpy_s(&g_cur_session->cmd_in, sizeof(g_cur_session->cmd_in), cmd, sizeof(*cmd)) != EOK) {
833 ret = TEE_ERROR_GENERIC;
834 goto open_fail;
835 }
836 ret = async_call_ta_entry(cmd, cmd_type, CALL_TA_OPEN_SESSION);
837 if (is_err_ret(ret)) {
838 tloge("Call TA Entry of service failed: 0x%x\n", ret);
839 goto open_fail;
840 }
841 g_cur_session->ta2ta_handle =
842 ((cmd_type != CMD_TYPE_SECURE_TO_SECURE) ? (INVALID_SESSION_HANDLE) : (ta2ta_info->handle));
843 do_resc_release_work(handle_ref_cnt);
844 return ret;
845 open_fail:
846 sre_ret = open_session_fail_gc();
847 create_task_fail_gc(handle_ref_cnt, sre_ret);
848 return ret;
849 }
850
release_session(struct service_struct * service,struct session_struct * session)851 int32_t release_session(struct service_struct *service, struct session_struct *session)
852 {
853 int32_t sre_ret;
854 uint32_t session_id;
855 struct service_struct *backup_service = NULL;
856 struct session_struct *backup_session = NULL;
857
858 if (service == NULL || session == NULL)
859 return (int32_t)TEE_ERROR_BAD_PARAMETERS;
860
861 task_adapt_unregister_ta(&service->property.uuid, session->task_id);
862 service->session_count--;
863
864 backup_service = g_cur_service;
865 backup_session = g_cur_session;
866 g_cur_service = service;
867 g_cur_session = session;
868 session_id = set_session_context_bit(service->index, session->session_id);
869 sre_ret = sre_task_delete_ex(session->task_id, service->is_service_dead, session_id);
870 if (sre_ret != SUCC_RET)
871 tloge("task del error fail 1\n");
872
873 release_pam_node(session->pam_node);
874 task_del_mem_region(&(session->map_mem), service->is_service_dead);
875
876 CLR_BIT(service->session_bitmap[get_index_by_uint32(session->session_id - 1)],
877 get_bit_by_uint32(session->session_id - 1));
878 dlist_delete(&session->session_list);
879 dlist_delete(&session->child_ta_sess_list);
880
881 /* Lose the locks held on agents */
882 tee_unlock_agents(session);
883
884 g_cur_service = backup_service;
885 g_cur_session = backup_session;
886 /* If we are on a waiting list remove it */
887 if (session->waiting_agent.next != NULL)
888 dlist_delete(&session->waiting_agent);
889
890 /*
891 * We are the last one to go, next
892 * open session will need to reinit
893 */
894 TEE_Free(session);
895
896 return sre_ret;
897 }
898
process_close_session_entry(struct service_struct ** service_in,struct session_struct ** session_in)899 TEE_Result process_close_session_entry(struct service_struct **service_in, struct session_struct **session_in)
900 {
901 struct service_struct *service = NULL;
902 struct session_struct *session = NULL;
903 bool check_status = ((service_in == NULL) || (session_in == NULL));
904 int32_t sre_ret;
905
906 if (check_status)
907 return TEE_ERROR_BAD_PARAMETERS;
908
909 service = *service_in;
910 session = *session_in;
911
912 check_status = ((service == NULL) || (session == NULL));
913 if (check_status)
914 return TEE_ERROR_BAD_PARAMETERS;
915
916 sre_ret = release_session(service, session);
917 session = NULL;
918 *session_in = NULL;
919
920 /* when service thread is blocked and session count is 0, we release service thread */
921 if (sre_ret == TIMEOUT_FAIL_RET) {
922 tloge("%s is blocked and session count is %u\n", service->name,
923 service->session_count);
924 if (service->session_count == 0) {
925 if (!is_build_in_service(&(service->property.uuid))) {
926 process_release_service(service, TA_REGION_RELEASE);
927 service = NULL;
928 *service_in = NULL;
929 } else {
930 service->init_build = 0;
931 recycle_srvc_thread(service);
932 }
933 }
934 return TEE_SUCCESS;
935 }
936
937 if (service->session_count == 0 && service->ref_cnt == 0) {
938 if (!is_build_in_service(&(service->property.uuid))) {
939 /* for non-keepalive TA, we release service node and service thread */
940 if (!service->property.keep_alive) {
941 process_release_service(service, TA_REGION_RELEASE);
942 service = NULL;
943 *service_in = NULL;
944 }
945 } else {
946 /*
947 * for non-keepalive TA, we need to recycle service thread
948 * and set init_build to 0 for restarting process.
949 */
950 if (!service->property.keep_alive) {
951 service->init_build = 0;
952 recycle_srvc_thread(service);
953 }
954 }
955 }
956 return TEE_SUCCESS;
957 }
958
do_target_session_close(struct session_struct * sess_context,struct service_struct * service_entry,uint32_t from_taskid,uint32_t level)959 static bool do_target_session_close(struct session_struct *sess_context, struct service_struct *service_entry,
960 uint32_t from_taskid, uint32_t level)
961 {
962 TEE_Result ret;
963 struct session_struct *sess = sess_context;
964 struct service_struct *srvc = service_entry;
965
966 if (sess->ta2ta_from_taskid == from_taskid) {
967 tlogd("ta2ta targert call session : %u\n", sess->session_id);
968
969 /* if level == MAX_TA2TA_LEVEL, it is the last level session */
970 if (level < MAX_TA2TA_LEVEL) {
971 tlogi("close next TA session level:%u\n", level);
972 process_close_ta2ta_target_sessions(sess->task_id, (level + 1));
973 }
974
975 ret = process_close_session_entry(&srvc, &sess);
976 if (ret != TEE_SUCCESS)
977 tloge("close ta2ta object session failed: errorno =0x%x\n", ret);
978 /*
979 * once service or session is released,
980 * we need to reiterate service list, otherwise,
981 * service_tmp or sess_tmp point to mem which has been released.
982 */
983 if (srvc == NULL || sess == NULL) {
984 tlogd("goto retry service list\n");
985 return true;
986 }
987 }
988 return false;
989 }
990
process_close_ta2ta_target_sessions(uint32_t from_taskid,uint32_t level)991 void process_close_ta2ta_target_sessions(uint32_t from_taskid, uint32_t level)
992 {
993 bool need_reiterate = false;
994 struct session_struct *sess_context = NULL;
995 struct session_struct *sess_tmp = NULL;
996 struct service_struct *service_entry = NULL;
997 struct service_struct *service_tmp = NULL;
998
999 /* Go through all the services and all sessions */
1000 do {
1001 dlist_for_each_entry_safe (service_entry, service_tmp, get_service_head_ptr(),
1002 struct service_struct, service_list) {
1003 if (service_entry->is_service_dead)
1004 continue;
1005 need_reiterate = false;
1006 tlogd("iterate service %s \n", service_entry->name);
1007 dlist_for_each_entry_safe (sess_context, sess_tmp, &service_entry->session_head, struct session_struct,
1008 session_list) {
1009 tlogd("iterate session %u \n", sess_context->session_id);
1010 need_reiterate = do_target_session_close(sess_context, service_entry, from_taskid, level);
1011 if (need_reiterate)
1012 break;
1013 }
1014 if (need_reiterate)
1015 break;
1016 }
1017 } while (need_reiterate);
1018 }
1019
process_close_session(void)1020 TEE_Result process_close_session(void)
1021 {
1022 TEE_Result ret;
1023
1024 if (g_cur_session == NULL)
1025 return TEE_ERROR_BAD_PARAMETERS;
1026
1027 process_close_ta2ta_target_sessions(g_cur_session->task_id, g_cur_session->ta2ta_level);
1028
1029 /* close current session itself */
1030 ret = process_close_session_entry(&g_cur_service, &g_cur_session);
1031 return ret;
1032 }
1033
process_open_session(const smc_cmd_t * cmd,uint32_t cmd_type)1034 TEE_Result process_open_session(const smc_cmd_t *cmd, uint32_t cmd_type)
1035 {
1036 global_to_ta_msg entry_msg = { 0 };
1037 uint32_t ret;
1038
1039 if (cmd == NULL)
1040 return TEE_ERROR_BAD_PARAMETERS;
1041
1042 bool check_stat = (g_cur_service == NULL || g_cur_session == NULL);
1043 if (check_stat)
1044 return TEE_ERROR_SESSION_NOT_EXIST;
1045
1046 if (g_cur_service->session_count == 1)
1047 entry_msg.first_session = 1;
1048
1049 entry_msg.session_id = set_session_context_bit(g_cur_service->index, g_cur_session->session_id);
1050 entry_msg.session_context = g_cur_session->session_context;
1051 entry_msg.cmd_id = cmd->cmd_id;
1052 entry_msg.dev_id = cmd->dev_file_id;
1053 entry_msg.started = cmd->started;
1054
1055 if (cmd_type == CMD_TYPE_NS_TO_SECURE) {
1056 if (cmd_ns_get_params(g_cur_session->task_id, cmd, &entry_msg.param_type, &entry_msg.params) != TEE_SUCCESS) {
1057 tloge("cmd_ns_get_params failed\n");
1058 goto map_error;
1059 }
1060 entry_msg.session_type = SESSION_FROM_CA;
1061 } else {
1062 if (TEE_SUCCESS !=
1063 cmd_secure_get_params(g_cur_session->task_id, cmd, &entry_msg.param_type, &entry_msg.params)) {
1064 tloge("cmd_secure_get_params failed\n");
1065 goto map_error;
1066 }
1067 entry_msg.session_type = SESSION_FROM_TA;
1068 }
1069
1070 ret = send_global2ta_msg(&entry_msg, CALL_TA_OPEN_SESSION, g_cur_session->task_id, NULL);
1071 if (ret != 0) {
1072 tloge("CALL_TA_OPEN_SESSION msg send to ta failed:0x%x\n", ret);
1073 return (TEE_Result)ret;
1074 }
1075 g_cur_session->wait_ta_back_msg = true;
1076 return TEE_SUCCESS;
1077 map_error:
1078 process_open_session_error();
1079 return TEE_ERROR_GENERIC;
1080 }
1081
process_open_session_error(void)1082 void process_open_session_error(void)
1083 {
1084 int sre_ret;
1085 uint32_t session_id;
1086
1087 task_adapt_unregister_ta(&g_cur_service->property.uuid, g_cur_session->task_id);
1088 release_pam_node(g_cur_session->pam_node);
1089 task_del_mem_region(&(g_cur_session->map_mem), false);
1090
1091 g_cur_service->session_count--;
1092
1093 session_id = set_session_context_bit(g_cur_service->index, g_cur_session->session_id);
1094 sre_ret = sre_task_delete_ex(g_cur_session->task_id, false, session_id);
1095 /* no return here, there's other clean work to do. */
1096 if (sre_ret != SUCC_RET)
1097 tloge("task del error fail 2: errorno =%d\n", sre_ret);
1098
1099 CLR_BIT(g_cur_service->session_bitmap[get_index_by_uint32(g_cur_session->session_id - 1)],
1100 get_bit_by_uint32(g_cur_session->session_id - 1));
1101 dlist_delete(&g_cur_session->session_list);
1102 dlist_delete(&g_cur_session->child_ta_sess_list);
1103 TEE_Free(g_cur_session);
1104 g_cur_session = (struct session_struct *)NULL;
1105
1106 /* when service thread is blocked and session count is 0, we release service thread */
1107 if (sre_ret == TIMEOUT_FAIL_RET) {
1108 tloge("%s is blocked and session count is %u\n", g_cur_service->name,
1109 g_cur_service->session_count);
1110 if (g_cur_service->session_count == 0) {
1111 if (!is_build_in_service(&(g_cur_service->property.uuid))) {
1112 process_release_service(g_cur_service, TA_REGION_RELEASE);
1113 g_cur_service = NULL;
1114 } else {
1115 g_cur_service->init_build = 0;
1116 recycle_srvc_thread(g_cur_service);
1117 }
1118 }
1119 return;
1120 }
1121
1122 /* release dynamic loaded TA's resource */
1123 if (g_cur_service->session_count == 0 && g_cur_service->ref_cnt == 0) {
1124 /* for non-keepalive TA, we release service node and service thread; */
1125 if (!is_build_in_service(&(g_cur_service->property.uuid))) {
1126 bool need_release_service = (!g_cur_service->property.keep_alive ||
1127 (g_cur_service->property.keep_alive && g_cur_service->first_open));
1128 if (need_release_service) {
1129 process_release_service(g_cur_service, TA_REGION_RELEASE);
1130 g_cur_service = NULL;
1131 }
1132 } else {
1133 /*
1134 * for non-keepalive TA, we release service thread
1135 * and set init_build to 0 for restarting process.
1136 */
1137 if (!g_cur_service->property.keep_alive) {
1138 g_cur_service->init_build = 0;
1139 recycle_srvc_thread(g_cur_service);
1140 }
1141 }
1142 }
1143 }
1144
process_init_session(void)1145 bool process_init_session(void)
1146 {
1147 if (g_cur_service == NULL || g_cur_session == NULL)
1148 return false;
1149
1150 /* send non-standard property */
1151 if (g_cur_service->property.other_buff != NULL && g_cur_service->property.other_len != 0) {
1152 tlogd("Have non-standard property!");
1153 uint32_t ret = ipc_msg_snd(CALL_TA_OPEN_SESSION_PROP, g_cur_session->task_id,
1154 g_cur_service->property.other_buff, (uint16_t)g_cur_service->property.other_len);
1155 if (ret != 0) {
1156 tloge("CALL_TA_OPEN_SESSION_PROP msg send to ta failed:0x%x\n", ret);
1157 return false;
1158 }
1159 g_cur_session->wait_ta_back_msg = true;
1160 return true;
1161 }
1162 return false;
1163 }
1164
close_session(const smc_cmd_t * cmd,uint32_t cmd_type,bool * sync)1165 TEE_Result close_session(const smc_cmd_t *cmd, uint32_t cmd_type, bool *sync)
1166 {
1167 TEE_Result ret;
1168
1169 if (cmd == NULL || sync == NULL || g_cur_service == NULL)
1170 return TEE_ERROR_BAD_PARAMETERS;
1171
1172 *sync = false;
1173
1174 if (is_gtask_by_uuid(&g_cur_service->property.uuid)) {
1175 /* Send the answer to caller right away since the command was already processed */
1176 *sync = true;
1177 return TEE_SUCCESS;
1178 }
1179
1180 bool check_stat = (g_cur_session == NULL || g_cur_session->session_id == 0 ||
1181 g_cur_session->session_id > MAX_SESSION_ID);
1182 if (check_stat) {
1183 tloge("close session not exist\n");
1184 return TEE_ERROR_SESSION_NOT_EXIST;
1185 }
1186
1187 if (memcpy_s(&g_cur_session->cmd_in, sizeof(smc_cmd_t), cmd, sizeof(smc_cmd_t)))
1188 return TEE_ERROR_GENERIC;
1189
1190 ret = async_call_ta_entry(cmd, cmd_type, CALL_TA_CLOSE_SESSION);
1191
1192 return ret;
1193 }
1194
close_session_async(struct session_struct * sess)1195 TEE_Result close_session_async(struct session_struct *sess)
1196 {
1197 if (sess == NULL) {
1198 tloge("invalid params\n");
1199 return TEE_ERROR_BAD_PARAMETERS;
1200 }
1201
1202 struct service_struct *service = find_service_by_task_id(sess->task_id);
1203 if (service == NULL) {
1204 tloge("find service by task id 0x%x failed, session id is 0x%x\n", sess->task_id, sess->session_id);
1205 return TEE_ERROR_SERVICE_NOT_EXIST;
1206 }
1207
1208 g_cur_service = service;
1209 g_cur_session = sess;
1210 tlogi("begin close service %s, session 0x%x async\n", service->name, sess->session_id);
1211 /* we reuse sess->cmd_in to do close session, operation_phys is invalid, so we clear it */
1212 sess->cmd_in.operation_phys = 0;
1213 sess->cmd_in.operation_h_phys = 0;
1214 return async_call_ta_entry(&(sess->cmd_in), sess->cmd_type, CALL_TA_CLOSE_SESSION);
1215 }
1216