1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2015-2016, Linaro Limited
4  * Copyright (c) 2014, STMicroelectronics International N.V.
5  */
6 
7 #include <assert.h>
8 #include <bench.h>
9 #include <compiler.h>
10 #include <initcall.h>
11 #include <io.h>
12 #include <kernel/linker.h>
13 #include <kernel/msg_param.h>
14 #include <kernel/notif.h>
15 #include <kernel/panic.h>
16 #include <kernel/tee_misc.h>
17 #include <mm/core_memprot.h>
18 #include <mm/core_mmu.h>
19 #include <mm/mobj.h>
20 #include <optee_msg.h>
21 #include <sm/optee_smc.h>
22 #include <string.h>
23 #include <tee/entry_std.h>
24 #include <tee/tee_cryp_utl.h>
25 #include <tee/uuid.h>
26 #include <util.h>
27 
28 #define SHM_CACHE_ATTRS	\
29 	(uint32_t)(core_mmu_is_shm_cached() ?  OPTEE_SMC_SHM_CACHED : 0)
30 
31 /* Sessions opened from normal world */
32 static struct tee_ta_session_head tee_open_sessions =
33 TAILQ_HEAD_INITIALIZER(tee_open_sessions);
34 
35 #ifdef CFG_CORE_RESERVED_SHM
36 static struct mobj *shm_mobj;
37 #endif
38 #ifdef CFG_SECURE_DATA_PATH
39 static struct mobj **sdp_mem_mobjs;
40 #endif
41 
42 static unsigned int session_pnum;
43 
param_mem_from_mobj(struct param_mem * mem,struct mobj * mobj,const paddr_t pa,const size_t sz)44 static bool __maybe_unused param_mem_from_mobj(struct param_mem *mem,
45 					       struct mobj *mobj,
46 					       const paddr_t pa,
47 					       const size_t sz)
48 {
49 	paddr_t b;
50 
51 	if (mobj_get_pa(mobj, 0, 0, &b) != TEE_SUCCESS)
52 		panic("mobj_get_pa failed");
53 
54 	if (!core_is_buffer_inside(pa, MAX(sz, 1UL), b, mobj->size))
55 		return false;
56 
57 	mem->mobj = mobj_get(mobj);
58 	mem->offs = pa - b;
59 	mem->size = sz;
60 	return true;
61 }
62 
63 #ifdef CFG_CORE_FFA
set_fmem_param(const struct optee_msg_param_fmem * fmem,struct param_mem * mem)64 static TEE_Result set_fmem_param(const struct optee_msg_param_fmem *fmem,
65 				 struct param_mem *mem)
66 {
67 	size_t req_size = 0;
68 	uint64_t global_id = READ_ONCE(fmem->global_id);
69 	size_t sz = READ_ONCE(fmem->size);
70 
71 	if (global_id == OPTEE_MSG_FMEM_INVALID_GLOBAL_ID && !sz) {
72 		mem->mobj = NULL;
73 		mem->offs = 0;
74 		mem->size = 0;
75 		return TEE_SUCCESS;
76 	}
77 	mem->mobj = mobj_ffa_get_by_cookie(global_id,
78 					   READ_ONCE(fmem->internal_offs));
79 	if (!mem->mobj)
80 		return TEE_ERROR_BAD_PARAMETERS;
81 
82 	mem->offs = reg_pair_to_64(READ_ONCE(fmem->offs_high),
83 				   READ_ONCE(fmem->offs_low));
84 	mem->size = sz;
85 
86 	/*
87 	 * Check that the supplied offset and size is covered by the
88 	 * previously verified MOBJ.
89 	 */
90 	if (ADD_OVERFLOW(mem->offs, mem->size, &req_size) ||
91 	    mem->mobj->size < req_size)
92 		return TEE_ERROR_SECURITY;
93 
94 	return TEE_SUCCESS;
95 }
96 #else /*!CFG_CORE_FFA*/
97 /* fill 'struct param_mem' structure if buffer matches a valid memory object */
set_tmem_param(const struct optee_msg_param_tmem * tmem,uint32_t attr,struct param_mem * mem)98 static TEE_Result set_tmem_param(const struct optee_msg_param_tmem *tmem,
99 				 uint32_t attr, struct param_mem *mem)
100 {
101 	struct mobj __maybe_unused **mobj;
102 	paddr_t pa = READ_ONCE(tmem->buf_ptr);
103 	size_t sz = READ_ONCE(tmem->size);
104 
105 	/*
106 	 * Handle NULL memory reference
107 	 */
108 	if (!pa) {
109 		mem->mobj = NULL;
110 		mem->offs = 0;
111 		mem->size = 0;
112 		return TEE_SUCCESS;
113 	}
114 
115 	/* Handle non-contiguous reference from a shared memory area */
116 	if (attr & OPTEE_MSG_ATTR_NONCONTIG) {
117 		uint64_t shm_ref = READ_ONCE(tmem->shm_ref);
118 
119 		mem->mobj = msg_param_mobj_from_noncontig(pa, sz, shm_ref,
120 							  false);
121 		if (!mem->mobj)
122 			return TEE_ERROR_BAD_PARAMETERS;
123 		mem->offs = 0;
124 		mem->size = sz;
125 		return TEE_SUCCESS;
126 	}
127 
128 #ifdef CFG_CORE_RESERVED_SHM
129 	/* Handle memory reference in the contiguous shared memory */
130 	if (param_mem_from_mobj(mem, shm_mobj, pa, sz))
131 		return TEE_SUCCESS;
132 #endif
133 
134 #ifdef CFG_SECURE_DATA_PATH
135 	/* Handle memory reference to Secure Data Path memory areas */
136 	for (mobj = sdp_mem_mobjs; *mobj; mobj++)
137 		if (param_mem_from_mobj(mem, *mobj, pa, sz))
138 			return TEE_SUCCESS;
139 #endif
140 
141 	return TEE_ERROR_BAD_PARAMETERS;
142 }
143 
144 #ifdef CFG_CORE_DYN_SHM
set_rmem_param(const struct optee_msg_param_rmem * rmem,struct param_mem * mem)145 static TEE_Result set_rmem_param(const struct optee_msg_param_rmem *rmem,
146 				 struct param_mem *mem)
147 {
148 	size_t req_size = 0;
149 	uint64_t shm_ref = READ_ONCE(rmem->shm_ref);
150 	size_t sz = READ_ONCE(rmem->size);
151 
152 	mem->mobj = mobj_reg_shm_get_by_cookie(shm_ref);
153 	if (!mem->mobj)
154 		return TEE_ERROR_BAD_PARAMETERS;
155 
156 	mem->offs = READ_ONCE(rmem->offs);
157 	mem->size = sz;
158 
159 	/*
160 	 * Check that the supplied offset and size is covered by the
161 	 * previously verified MOBJ.
162 	 */
163 	if (ADD_OVERFLOW(mem->offs, mem->size, &req_size) ||
164 	    mem->mobj->size < req_size)
165 		return TEE_ERROR_SECURITY;
166 
167 	return TEE_SUCCESS;
168 }
169 #endif /*CFG_CORE_DYN_SHM*/
170 #endif /*!CFG_CORE_FFA*/
171 
copy_in_params(const struct optee_msg_param * params,uint32_t num_params,struct tee_ta_param * ta_param,uint64_t * saved_attr)172 static TEE_Result copy_in_params(const struct optee_msg_param *params,
173 				 uint32_t num_params,
174 				 struct tee_ta_param *ta_param,
175 				 uint64_t *saved_attr)
176 {
177 	TEE_Result res;
178 	size_t n;
179 	uint8_t pt[TEE_NUM_PARAMS] = { 0 };
180 
181 	if (num_params > TEE_NUM_PARAMS)
182 		return TEE_ERROR_BAD_PARAMETERS;
183 
184 	memset(ta_param, 0, sizeof(*ta_param));
185 
186 	for (n = 0; n < num_params; n++) {
187 		uint32_t attr;
188 
189 		saved_attr[n] = READ_ONCE(params[n].attr);
190 
191 		if (saved_attr[n] & OPTEE_MSG_ATTR_META)
192 			return TEE_ERROR_BAD_PARAMETERS;
193 
194 		attr = saved_attr[n] & OPTEE_MSG_ATTR_TYPE_MASK;
195 		switch (attr) {
196 		case OPTEE_MSG_ATTR_TYPE_NONE:
197 			pt[n] = TEE_PARAM_TYPE_NONE;
198 			break;
199 		case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
200 		case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
201 		case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
202 			pt[n] = TEE_PARAM_TYPE_VALUE_INPUT + attr -
203 				OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
204 			ta_param->u[n].val.a = READ_ONCE(params[n].u.value.a);
205 			ta_param->u[n].val.b = READ_ONCE(params[n].u.value.b);
206 			break;
207 #ifdef CFG_CORE_FFA
208 		case OPTEE_MSG_ATTR_TYPE_FMEM_INPUT:
209 		case OPTEE_MSG_ATTR_TYPE_FMEM_OUTPUT:
210 		case OPTEE_MSG_ATTR_TYPE_FMEM_INOUT:
211 			res = set_fmem_param(&params[n].u.fmem,
212 					     &ta_param->u[n].mem);
213 			if (res)
214 				return res;
215 			pt[n] = TEE_PARAM_TYPE_MEMREF_INPUT + attr -
216 				OPTEE_MSG_ATTR_TYPE_FMEM_INPUT;
217 			break;
218 #else /*!CFG_CORE_FFA*/
219 		case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT:
220 		case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT:
221 		case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT:
222 			res = set_tmem_param(&params[n].u.tmem, saved_attr[n],
223 					     &ta_param->u[n].mem);
224 			if (res)
225 				return res;
226 			pt[n] = TEE_PARAM_TYPE_MEMREF_INPUT + attr -
227 				OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
228 			break;
229 #ifdef CFG_CORE_DYN_SHM
230 		case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT:
231 		case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
232 		case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT:
233 			res = set_rmem_param(&params[n].u.rmem,
234 					     &ta_param->u[n].mem);
235 			if (res)
236 				return res;
237 			pt[n] = TEE_PARAM_TYPE_MEMREF_INPUT + attr -
238 				OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
239 			break;
240 #endif /*CFG_CORE_DYN_SHM*/
241 #endif /*!CFG_CORE_FFA*/
242 		default:
243 			return TEE_ERROR_BAD_PARAMETERS;
244 		}
245 	}
246 
247 	ta_param->types = TEE_PARAM_TYPES(pt[0], pt[1], pt[2], pt[3]);
248 
249 	return TEE_SUCCESS;
250 }
251 
cleanup_shm_refs(const uint64_t * saved_attr,struct tee_ta_param * param,uint32_t num_params)252 static void cleanup_shm_refs(const uint64_t *saved_attr,
253 			     struct tee_ta_param *param, uint32_t num_params)
254 {
255 	size_t n;
256 
257 	for (n = 0; n < num_params; n++) {
258 		switch (saved_attr[n]) {
259 		case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT:
260 		case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT:
261 		case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT:
262 #ifdef CFG_CORE_DYN_SHM
263 		case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT:
264 		case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
265 		case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT:
266 #endif
267 			mobj_put(param->u[n].mem.mobj);
268 			break;
269 		default:
270 			break;
271 		}
272 	}
273 }
274 
copy_out_param(struct tee_ta_param * ta_param,uint32_t num_params,struct optee_msg_param * params,uint64_t * saved_attr)275 static void copy_out_param(struct tee_ta_param *ta_param, uint32_t num_params,
276 			   struct optee_msg_param *params, uint64_t *saved_attr)
277 {
278 	size_t n;
279 
280 	for (n = 0; n < num_params; n++) {
281 		switch (TEE_PARAM_TYPE_GET(ta_param->types, n)) {
282 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
283 		case TEE_PARAM_TYPE_MEMREF_INOUT:
284 			switch (saved_attr[n] & OPTEE_MSG_ATTR_TYPE_MASK) {
285 			case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT:
286 			case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT:
287 				params[n].u.tmem.size = ta_param->u[n].mem.size;
288 				break;
289 			case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
290 			case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT:
291 				params[n].u.rmem.size = ta_param->u[n].mem.size;
292 				break;
293 			default:
294 				break;
295 			}
296 			break;
297 		case TEE_PARAM_TYPE_VALUE_OUTPUT:
298 		case TEE_PARAM_TYPE_VALUE_INOUT:
299 			params[n].u.value.a = ta_param->u[n].val.a;
300 			params[n].u.value.b = ta_param->u[n].val.b;
301 			break;
302 		default:
303 			break;
304 		}
305 	}
306 }
307 
308 /*
309  * Extracts mandatory parameter for open session.
310  *
311  * Returns
312  * false : mandatory parameter wasn't found or malformatted
313  * true  : paramater found and OK
314  */
get_open_session_meta(size_t num_params,struct optee_msg_param * params,size_t * num_meta,TEE_UUID * uuid,TEE_Identity * clnt_id)315 static TEE_Result get_open_session_meta(size_t num_params,
316 					struct optee_msg_param *params,
317 					size_t *num_meta, TEE_UUID *uuid,
318 					TEE_Identity *clnt_id)
319 {
320 	const uint32_t req_attr = OPTEE_MSG_ATTR_META |
321 				  OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
322 
323 	if (num_params < 2)
324 		return TEE_ERROR_BAD_PARAMETERS;
325 
326 	if (params[0].attr != req_attr || params[1].attr != req_attr)
327 		return TEE_ERROR_BAD_PARAMETERS;
328 
329 	tee_uuid_from_octets(uuid, (void *)&params[0].u.value);
330 	clnt_id->login = params[1].u.value.c;
331 	switch (clnt_id->login) {
332 	case TEE_LOGIN_PUBLIC:
333 	case TEE_LOGIN_REE_KERNEL:
334 		memset(&clnt_id->uuid, 0, sizeof(clnt_id->uuid));
335 		break;
336 	case TEE_LOGIN_USER:
337 	case TEE_LOGIN_GROUP:
338 	case TEE_LOGIN_APPLICATION:
339 	case TEE_LOGIN_APPLICATION_USER:
340 	case TEE_LOGIN_APPLICATION_GROUP:
341 		tee_uuid_from_octets(&clnt_id->uuid,
342 				     (void *)&params[1].u.value);
343 		break;
344 	default:
345 		return TEE_ERROR_BAD_PARAMETERS;
346 	}
347 
348 	*num_meta = 2;
349 	return TEE_SUCCESS;
350 }
351 
entry_open_session(struct optee_msg_arg * arg,uint32_t num_params)352 static void entry_open_session(struct optee_msg_arg *arg, uint32_t num_params)
353 {
354 	TEE_Result res;
355 	TEE_ErrorOrigin err_orig = TEE_ORIGIN_TEE;
356 	struct tee_ta_session *s = NULL;
357 	TEE_Identity clnt_id;
358 	TEE_UUID uuid;
359 	struct tee_ta_param param;
360 	size_t num_meta;
361 	uint64_t saved_attr[TEE_NUM_PARAMS] = { 0 };
362 
363 	res = get_open_session_meta(num_params, arg->params, &num_meta, &uuid,
364 				    &clnt_id);
365 	if (res != TEE_SUCCESS)
366 		goto out;
367 
368 	res = copy_in_params(arg->params + num_meta, num_params - num_meta,
369 			     &param, saved_attr);
370 	if (res != TEE_SUCCESS)
371 		goto cleanup_shm_refs;
372 
373 	res = tee_ta_open_session(&err_orig, &s, &tee_open_sessions, &uuid,
374 				  &clnt_id, TEE_TIMEOUT_INFINITE, &param);
375 	if (res != TEE_SUCCESS)
376 		s = NULL;
377 	copy_out_param(&param, num_params - num_meta, arg->params + num_meta,
378 		       saved_attr);
379 
380 	/*
381 	 * The occurrence of open/close session command is usually
382 	 * un-predictable, using this property to increase randomness
383 	 * of prng
384 	 */
385 	plat_prng_add_jitter_entropy(CRYPTO_RNG_SRC_JITTER_SESSION,
386 				     &session_pnum);
387 
388 cleanup_shm_refs:
389 	cleanup_shm_refs(saved_attr, &param, num_params - num_meta);
390 
391 out:
392 	if (s)
393 		arg->session = s->id;
394 	else
395 		arg->session = 0;
396 	arg->ret = res;
397 	arg->ret_origin = err_orig;
398 }
399 
entry_close_session(struct optee_msg_arg * arg,uint32_t num_params)400 static void entry_close_session(struct optee_msg_arg *arg, uint32_t num_params)
401 {
402 	TEE_Result res;
403 	struct tee_ta_session *s;
404 
405 	if (num_params) {
406 		res = TEE_ERROR_BAD_PARAMETERS;
407 		goto out;
408 	}
409 
410 	plat_prng_add_jitter_entropy(CRYPTO_RNG_SRC_JITTER_SESSION,
411 				     &session_pnum);
412 
413 	s = tee_ta_find_session(arg->session, &tee_open_sessions);
414 	res = tee_ta_close_session(s, &tee_open_sessions, NSAPP_IDENTITY);
415 out:
416 	arg->ret = res;
417 	arg->ret_origin = TEE_ORIGIN_TEE;
418 }
419 
entry_invoke_command(struct optee_msg_arg * arg,uint32_t num_params)420 static void entry_invoke_command(struct optee_msg_arg *arg, uint32_t num_params)
421 {
422 	TEE_Result res;
423 	TEE_ErrorOrigin err_orig = TEE_ORIGIN_TEE;
424 	struct tee_ta_session *s;
425 	struct tee_ta_param param = { 0 };
426 	uint64_t saved_attr[TEE_NUM_PARAMS] = { 0 };
427 
428 	bm_timestamp();
429 
430 	res = copy_in_params(arg->params, num_params, &param, saved_attr);
431 	if (res != TEE_SUCCESS)
432 		goto out;
433 
434 	s = tee_ta_get_session(arg->session, true, &tee_open_sessions);
435 	if (!s) {
436 		res = TEE_ERROR_BAD_PARAMETERS;
437 		goto out;
438 	}
439 
440 	res = tee_ta_invoke_command(&err_orig, s, NSAPP_IDENTITY,
441 				    TEE_TIMEOUT_INFINITE, arg->func, &param);
442 
443 	bm_timestamp();
444 
445 	tee_ta_put_session(s);
446 
447 	copy_out_param(&param, num_params, arg->params, saved_attr);
448 
449 out:
450 	cleanup_shm_refs(saved_attr, &param, num_params);
451 
452 	arg->ret = res;
453 	arg->ret_origin = err_orig;
454 }
455 
entry_cancel(struct optee_msg_arg * arg,uint32_t num_params)456 static void entry_cancel(struct optee_msg_arg *arg, uint32_t num_params)
457 {
458 	TEE_Result res;
459 	TEE_ErrorOrigin err_orig = TEE_ORIGIN_TEE;
460 	struct tee_ta_session *s;
461 
462 	if (num_params) {
463 		res = TEE_ERROR_BAD_PARAMETERS;
464 		goto out;
465 	}
466 
467 	s = tee_ta_get_session(arg->session, false, &tee_open_sessions);
468 	if (!s) {
469 		res = TEE_ERROR_BAD_PARAMETERS;
470 		goto out;
471 	}
472 
473 	res = tee_ta_cancel_command(&err_orig, s, NSAPP_IDENTITY);
474 	tee_ta_put_session(s);
475 
476 out:
477 	arg->ret = res;
478 	arg->ret_origin = err_orig;
479 }
480 
481 #ifndef CFG_CORE_FFA
482 #ifdef CFG_CORE_DYN_SHM
register_shm(struct optee_msg_arg * arg,uint32_t num_params)483 static void register_shm(struct optee_msg_arg *arg, uint32_t num_params)
484 {
485 	struct optee_msg_param_tmem *tmem = NULL;
486 	struct mobj *mobj = NULL;
487 
488 	arg->ret = TEE_ERROR_BAD_PARAMETERS;
489 
490 	if (num_params != 1 ||
491 	    (arg->params[0].attr !=
492 	     (OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT | OPTEE_MSG_ATTR_NONCONTIG)))
493 		return;
494 
495 	tmem = &arg->params[0].u.tmem;
496 	mobj = msg_param_mobj_from_noncontig(tmem->buf_ptr, tmem->size,
497 					     tmem->shm_ref, false);
498 
499 	if (!mobj)
500 		return;
501 
502 	mobj_reg_shm_unguard(mobj);
503 	arg->ret = TEE_SUCCESS;
504 }
505 
unregister_shm(struct optee_msg_arg * arg,uint32_t num_params)506 static void unregister_shm(struct optee_msg_arg *arg, uint32_t num_params)
507 {
508 	if (num_params == 1) {
509 		uint64_t cookie = arg->params[0].u.rmem.shm_ref;
510 		TEE_Result res = mobj_reg_shm_release_by_cookie(cookie);
511 
512 		if (res)
513 			EMSG("Can't find mapping with given cookie");
514 		arg->ret = res;
515 	} else {
516 		arg->ret = TEE_ERROR_BAD_PARAMETERS;
517 		arg->ret_origin = TEE_ORIGIN_TEE;
518 	}
519 }
520 #endif /*CFG_CORE_DYN_SHM*/
521 #endif
522 
nsec_sessions_list_head(struct tee_ta_session_head ** open_sessions)523 void nsec_sessions_list_head(struct tee_ta_session_head **open_sessions)
524 {
525 	*open_sessions = &tee_open_sessions;
526 }
527 
528 /* Note: this function is weak to let platforms add special handling */
tee_entry_std(struct optee_msg_arg * arg,uint32_t num_params)529 uint32_t __weak tee_entry_std(struct optee_msg_arg *arg, uint32_t num_params)
530 {
531 	return __tee_entry_std(arg, num_params);
532 }
533 
534 /*
535  * If tee_entry_std() is overridden, it's still supposed to call this
536  * function.
537  */
__tee_entry_std(struct optee_msg_arg * arg,uint32_t num_params)538 uint32_t __tee_entry_std(struct optee_msg_arg *arg, uint32_t num_params)
539 {
540 	uint32_t rv = OPTEE_SMC_RETURN_OK;
541 
542 	/* Enable foreign interrupts for STD calls */
543 	thread_set_foreign_intr(true);
544 	switch (arg->cmd) {
545 	case OPTEE_MSG_CMD_OPEN_SESSION:
546 		entry_open_session(arg, num_params);
547 		break;
548 	case OPTEE_MSG_CMD_CLOSE_SESSION:
549 		entry_close_session(arg, num_params);
550 		break;
551 	case OPTEE_MSG_CMD_INVOKE_COMMAND:
552 		entry_invoke_command(arg, num_params);
553 		break;
554 	case OPTEE_MSG_CMD_CANCEL:
555 		entry_cancel(arg, num_params);
556 		break;
557 #ifndef CFG_CORE_FFA
558 #ifdef CFG_CORE_DYN_SHM
559 	case OPTEE_MSG_CMD_REGISTER_SHM:
560 		register_shm(arg, num_params);
561 		break;
562 	case OPTEE_MSG_CMD_UNREGISTER_SHM:
563 		unregister_shm(arg, num_params);
564 		break;
565 #endif
566 #endif
567 
568 	case OPTEE_MSG_CMD_DO_BOTTOM_HALF:
569 		if (IS_ENABLED(CFG_CORE_ASYNC_NOTIF))
570 			notif_deliver_event(NOTIF_EVENT_DO_BOTTOM_HALF);
571 		else
572 			goto err;
573 		break;
574 	case OPTEE_MSG_CMD_STOP_ASYNC_NOTIF:
575 		if (IS_ENABLED(CFG_CORE_ASYNC_NOTIF))
576 			notif_deliver_event(NOTIF_EVENT_STOPPED);
577 		else
578 			goto err;
579 		break;
580 
581 	default:
582 err:
583 		EMSG("Unknown cmd 0x%x", arg->cmd);
584 		rv = OPTEE_SMC_RETURN_EBADCMD;
585 	}
586 
587 	return rv;
588 }
589 
default_mobj_init(void)590 static TEE_Result default_mobj_init(void)
591 {
592 #ifdef CFG_CORE_RESERVED_SHM
593 	shm_mobj = mobj_phys_alloc(default_nsec_shm_paddr,
594 				   default_nsec_shm_size, SHM_CACHE_ATTRS,
595 				   CORE_MEM_NSEC_SHM);
596 	if (!shm_mobj)
597 		panic("Failed to register shared memory");
598 #endif
599 
600 #ifdef CFG_SECURE_DATA_PATH
601 	sdp_mem_mobjs = core_sdp_mem_create_mobjs();
602 	if (!sdp_mem_mobjs)
603 		panic("Failed to register SDP memory");
604 #endif
605 
606 	return TEE_SUCCESS;
607 }
608 
609 driver_init_late(default_mobj_init);
610