125c76675SMarouene Boubakri // SPDX-License-Identifier: BSD-2-Clause
225c76675SMarouene Boubakri /*
325c76675SMarouene Boubakri * Copyright (c) 2015-2016, Linaro Limited
425c76675SMarouene Boubakri * Copyright (c) 2014, STMicroelectronics International N.V.
525c76675SMarouene Boubakri */
625c76675SMarouene Boubakri
725c76675SMarouene Boubakri #include <assert.h>
825c76675SMarouene Boubakri #include <compiler.h>
925c76675SMarouene Boubakri #include <initcall.h>
1025c76675SMarouene Boubakri #include <io.h>
1125c76675SMarouene Boubakri #include <kernel/linker.h>
1225c76675SMarouene Boubakri #include <kernel/msg_param.h>
13c2d44948SJens Wiklander #include <kernel/notif.h>
1425c76675SMarouene Boubakri #include <kernel/panic.h>
1525c76675SMarouene Boubakri #include <kernel/tee_misc.h>
1625c76675SMarouene Boubakri #include <mm/core_memprot.h>
1725c76675SMarouene Boubakri #include <mm/core_mmu.h>
1825c76675SMarouene Boubakri #include <mm/mobj.h>
1925c76675SMarouene Boubakri #include <optee_msg.h>
2025c76675SMarouene Boubakri #include <string.h>
2125c76675SMarouene Boubakri #include <tee/entry_std.h>
2225c76675SMarouene Boubakri #include <tee/tee_cryp_utl.h>
2325c76675SMarouene Boubakri #include <tee/uuid.h>
2425c76675SMarouene Boubakri #include <util.h>
2525c76675SMarouene Boubakri
26*00338334SJens Wiklander #ifdef CFG_CORE_FFA
27*00338334SJens Wiklander #include <kernel/thread_spmc.h>
28*00338334SJens Wiklander #endif
29*00338334SJens Wiklander
3025c76675SMarouene Boubakri #define SHM_CACHE_ATTRS \
31d8158feaSJens Wiklander (uint32_t)(core_mmu_is_shm_cached() ? \
328b427282SJelle Sels TEE_MATTR_MEM_TYPE_CACHED : TEE_MATTR_MEM_TYPE_DEV)
3325c76675SMarouene Boubakri
3425c76675SMarouene Boubakri /* Sessions opened from normal world */
3525c76675SMarouene Boubakri static struct tee_ta_session_head tee_open_sessions =
3625c76675SMarouene Boubakri TAILQ_HEAD_INITIALIZER(tee_open_sessions);
3725c76675SMarouene Boubakri
3825c76675SMarouene Boubakri #ifdef CFG_CORE_RESERVED_SHM
3925c76675SMarouene Boubakri static struct mobj *shm_mobj;
4025c76675SMarouene Boubakri #endif
4125c76675SMarouene Boubakri #ifdef CFG_SECURE_DATA_PATH
4225c76675SMarouene Boubakri static struct mobj **sdp_mem_mobjs;
4325c76675SMarouene Boubakri #endif
4425c76675SMarouene Boubakri
4525c76675SMarouene Boubakri static unsigned int session_pnum;
4625c76675SMarouene Boubakri
param_mem_from_mobj(struct param_mem * mem,struct mobj * mobj,const paddr_t pa,const size_t sz)4725c76675SMarouene Boubakri static bool __maybe_unused param_mem_from_mobj(struct param_mem *mem,
4825c76675SMarouene Boubakri struct mobj *mobj,
4925c76675SMarouene Boubakri const paddr_t pa,
5025c76675SMarouene Boubakri const size_t sz)
5125c76675SMarouene Boubakri {
5225c76675SMarouene Boubakri paddr_t b;
5325c76675SMarouene Boubakri
5425c76675SMarouene Boubakri if (mobj_get_pa(mobj, 0, 0, &b) != TEE_SUCCESS)
5525c76675SMarouene Boubakri panic("mobj_get_pa failed");
5625c76675SMarouene Boubakri
5725c76675SMarouene Boubakri if (!core_is_buffer_inside(pa, MAX(sz, 1UL), b, mobj->size))
5825c76675SMarouene Boubakri return false;
5925c76675SMarouene Boubakri
6025c76675SMarouene Boubakri mem->mobj = mobj_get(mobj);
6125c76675SMarouene Boubakri mem->offs = pa - b;
6225c76675SMarouene Boubakri mem->size = sz;
6325c76675SMarouene Boubakri return true;
6425c76675SMarouene Boubakri }
6525c76675SMarouene Boubakri
6625c76675SMarouene Boubakri #ifdef CFG_CORE_FFA
set_fmem_param(const struct optee_msg_param_fmem * fmem,struct param_mem * mem)6725c76675SMarouene Boubakri static TEE_Result set_fmem_param(const struct optee_msg_param_fmem *fmem,
6825c76675SMarouene Boubakri struct param_mem *mem)
6925c76675SMarouene Boubakri {
7025c76675SMarouene Boubakri size_t req_size = 0;
7125c76675SMarouene Boubakri uint64_t global_id = READ_ONCE(fmem->global_id);
7225c76675SMarouene Boubakri size_t sz = READ_ONCE(fmem->size);
7325c76675SMarouene Boubakri
74c1bdf4fcSJens Wiklander if (global_id == OPTEE_MSG_FMEM_INVALID_GLOBAL_ID && !sz) {
7525c76675SMarouene Boubakri mem->mobj = NULL;
7625c76675SMarouene Boubakri mem->offs = 0;
7725c76675SMarouene Boubakri mem->size = 0;
7825c76675SMarouene Boubakri return TEE_SUCCESS;
7925c76675SMarouene Boubakri }
8025c76675SMarouene Boubakri mem->mobj = mobj_ffa_get_by_cookie(global_id,
8125c76675SMarouene Boubakri READ_ONCE(fmem->internal_offs));
8225c76675SMarouene Boubakri if (!mem->mobj)
8325c76675SMarouene Boubakri return TEE_ERROR_BAD_PARAMETERS;
8425c76675SMarouene Boubakri
8525c76675SMarouene Boubakri mem->offs = reg_pair_to_64(READ_ONCE(fmem->offs_high),
8625c76675SMarouene Boubakri READ_ONCE(fmem->offs_low));
8725c76675SMarouene Boubakri mem->size = sz;
8825c76675SMarouene Boubakri
8925c76675SMarouene Boubakri /*
9025c76675SMarouene Boubakri * Check that the supplied offset and size is covered by the
9125c76675SMarouene Boubakri * previously verified MOBJ.
9225c76675SMarouene Boubakri */
9325c76675SMarouene Boubakri if (ADD_OVERFLOW(mem->offs, mem->size, &req_size) ||
9425c76675SMarouene Boubakri mem->mobj->size < req_size)
9525c76675SMarouene Boubakri return TEE_ERROR_SECURITY;
9625c76675SMarouene Boubakri
9725c76675SMarouene Boubakri return TEE_SUCCESS;
9825c76675SMarouene Boubakri }
9925c76675SMarouene Boubakri #else /*!CFG_CORE_FFA*/
10025c76675SMarouene Boubakri /* 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)10125c76675SMarouene Boubakri static TEE_Result set_tmem_param(const struct optee_msg_param_tmem *tmem,
10225c76675SMarouene Boubakri uint32_t attr, struct param_mem *mem)
10325c76675SMarouene Boubakri {
104*00338334SJens Wiklander struct mobj __maybe_unused **mobj = NULL;
10525c76675SMarouene Boubakri paddr_t pa = READ_ONCE(tmem->buf_ptr);
10625c76675SMarouene Boubakri size_t sz = READ_ONCE(tmem->size);
107*00338334SJens Wiklander struct mobj *rmobj = NULL;
10825c76675SMarouene Boubakri
10925c76675SMarouene Boubakri /*
11025c76675SMarouene Boubakri * Handle NULL memory reference
11125c76675SMarouene Boubakri */
11225c76675SMarouene Boubakri if (!pa) {
11325c76675SMarouene Boubakri mem->mobj = NULL;
11425c76675SMarouene Boubakri mem->offs = 0;
11525c76675SMarouene Boubakri mem->size = 0;
11625c76675SMarouene Boubakri return TEE_SUCCESS;
11725c76675SMarouene Boubakri }
11825c76675SMarouene Boubakri
11925c76675SMarouene Boubakri /* Handle non-contiguous reference from a shared memory area */
12025c76675SMarouene Boubakri if (attr & OPTEE_MSG_ATTR_NONCONTIG) {
12125c76675SMarouene Boubakri uint64_t shm_ref = READ_ONCE(tmem->shm_ref);
12225c76675SMarouene Boubakri
12325c76675SMarouene Boubakri mem->mobj = msg_param_mobj_from_noncontig(pa, sz, shm_ref,
12425c76675SMarouene Boubakri false);
12525c76675SMarouene Boubakri if (!mem->mobj)
12625c76675SMarouene Boubakri return TEE_ERROR_BAD_PARAMETERS;
12725c76675SMarouene Boubakri mem->offs = 0;
12825c76675SMarouene Boubakri mem->size = sz;
12925c76675SMarouene Boubakri return TEE_SUCCESS;
13025c76675SMarouene Boubakri }
13125c76675SMarouene Boubakri
13225c76675SMarouene Boubakri #ifdef CFG_CORE_RESERVED_SHM
13325c76675SMarouene Boubakri /* Handle memory reference in the contiguous shared memory */
13425c76675SMarouene Boubakri if (param_mem_from_mobj(mem, shm_mobj, pa, sz))
13525c76675SMarouene Boubakri return TEE_SUCCESS;
13625c76675SMarouene Boubakri #endif
13725c76675SMarouene Boubakri
13825c76675SMarouene Boubakri #ifdef CFG_SECURE_DATA_PATH
13925c76675SMarouene Boubakri /* Handle memory reference to Secure Data Path memory areas */
14025c76675SMarouene Boubakri for (mobj = sdp_mem_mobjs; *mobj; mobj++)
14125c76675SMarouene Boubakri if (param_mem_from_mobj(mem, *mobj, pa, sz))
14225c76675SMarouene Boubakri return TEE_SUCCESS;
14325c76675SMarouene Boubakri #endif
144*00338334SJens Wiklander rmobj = mobj_protmem_get_by_pa(pa, sz);
145*00338334SJens Wiklander if (rmobj) {
146*00338334SJens Wiklander bool rc = param_mem_from_mobj(mem, rmobj, pa, sz);
147*00338334SJens Wiklander
148*00338334SJens Wiklander mobj_put(rmobj);
149*00338334SJens Wiklander if (rc)
150*00338334SJens Wiklander return TEE_SUCCESS;
151*00338334SJens Wiklander }
15225c76675SMarouene Boubakri
15325c76675SMarouene Boubakri return TEE_ERROR_BAD_PARAMETERS;
15425c76675SMarouene Boubakri }
15525c76675SMarouene Boubakri
15625c76675SMarouene Boubakri #ifdef CFG_CORE_DYN_SHM
set_rmem_param(const struct optee_msg_param_rmem * rmem,struct param_mem * mem)15725c76675SMarouene Boubakri static TEE_Result set_rmem_param(const struct optee_msg_param_rmem *rmem,
15825c76675SMarouene Boubakri struct param_mem *mem)
15925c76675SMarouene Boubakri {
16025c76675SMarouene Boubakri size_t req_size = 0;
16125c76675SMarouene Boubakri uint64_t shm_ref = READ_ONCE(rmem->shm_ref);
16225c76675SMarouene Boubakri size_t sz = READ_ONCE(rmem->size);
16325c76675SMarouene Boubakri
16425c76675SMarouene Boubakri mem->mobj = mobj_reg_shm_get_by_cookie(shm_ref);
16525c76675SMarouene Boubakri if (!mem->mobj)
16625c76675SMarouene Boubakri return TEE_ERROR_BAD_PARAMETERS;
16725c76675SMarouene Boubakri
16825c76675SMarouene Boubakri mem->offs = READ_ONCE(rmem->offs);
16925c76675SMarouene Boubakri mem->size = sz;
17025c76675SMarouene Boubakri
17125c76675SMarouene Boubakri /*
17225c76675SMarouene Boubakri * Check that the supplied offset and size is covered by the
17325c76675SMarouene Boubakri * previously verified MOBJ.
17425c76675SMarouene Boubakri */
17525c76675SMarouene Boubakri if (ADD_OVERFLOW(mem->offs, mem->size, &req_size) ||
17625c76675SMarouene Boubakri mem->mobj->size < req_size)
17725c76675SMarouene Boubakri return TEE_ERROR_SECURITY;
17825c76675SMarouene Boubakri
17925c76675SMarouene Boubakri return TEE_SUCCESS;
18025c76675SMarouene Boubakri }
18125c76675SMarouene Boubakri #endif /*CFG_CORE_DYN_SHM*/
18225c76675SMarouene Boubakri #endif /*!CFG_CORE_FFA*/
18325c76675SMarouene Boubakri
copy_in_params(const struct optee_msg_param * params,uint32_t num_params,struct tee_ta_param * ta_param,uint64_t * saved_attr)18425c76675SMarouene Boubakri static TEE_Result copy_in_params(const struct optee_msg_param *params,
18525c76675SMarouene Boubakri uint32_t num_params,
18625c76675SMarouene Boubakri struct tee_ta_param *ta_param,
18725c76675SMarouene Boubakri uint64_t *saved_attr)
18825c76675SMarouene Boubakri {
18925c76675SMarouene Boubakri TEE_Result res;
19025c76675SMarouene Boubakri size_t n;
19125c76675SMarouene Boubakri uint8_t pt[TEE_NUM_PARAMS] = { 0 };
19225c76675SMarouene Boubakri
19325c76675SMarouene Boubakri if (num_params > TEE_NUM_PARAMS)
19425c76675SMarouene Boubakri return TEE_ERROR_BAD_PARAMETERS;
19525c76675SMarouene Boubakri
19625c76675SMarouene Boubakri memset(ta_param, 0, sizeof(*ta_param));
19725c76675SMarouene Boubakri
19825c76675SMarouene Boubakri for (n = 0; n < num_params; n++) {
19925c76675SMarouene Boubakri uint32_t attr;
20025c76675SMarouene Boubakri
20125c76675SMarouene Boubakri saved_attr[n] = READ_ONCE(params[n].attr);
20225c76675SMarouene Boubakri
20325c76675SMarouene Boubakri if (saved_attr[n] & OPTEE_MSG_ATTR_META)
20425c76675SMarouene Boubakri return TEE_ERROR_BAD_PARAMETERS;
20525c76675SMarouene Boubakri
20625c76675SMarouene Boubakri attr = saved_attr[n] & OPTEE_MSG_ATTR_TYPE_MASK;
20725c76675SMarouene Boubakri switch (attr) {
20825c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_NONE:
20925c76675SMarouene Boubakri pt[n] = TEE_PARAM_TYPE_NONE;
21025c76675SMarouene Boubakri break;
21125c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
21225c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
21325c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
21425c76675SMarouene Boubakri pt[n] = TEE_PARAM_TYPE_VALUE_INPUT + attr -
21525c76675SMarouene Boubakri OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
21625c76675SMarouene Boubakri ta_param->u[n].val.a = READ_ONCE(params[n].u.value.a);
21725c76675SMarouene Boubakri ta_param->u[n].val.b = READ_ONCE(params[n].u.value.b);
21825c76675SMarouene Boubakri break;
21925c76675SMarouene Boubakri #ifdef CFG_CORE_FFA
22025c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_FMEM_INPUT:
22125c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_FMEM_OUTPUT:
22225c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_FMEM_INOUT:
22325c76675SMarouene Boubakri res = set_fmem_param(¶ms[n].u.fmem,
22425c76675SMarouene Boubakri &ta_param->u[n].mem);
22525c76675SMarouene Boubakri if (res)
22625c76675SMarouene Boubakri return res;
22725c76675SMarouene Boubakri pt[n] = TEE_PARAM_TYPE_MEMREF_INPUT + attr -
22825c76675SMarouene Boubakri OPTEE_MSG_ATTR_TYPE_FMEM_INPUT;
22925c76675SMarouene Boubakri break;
23025c76675SMarouene Boubakri #else /*!CFG_CORE_FFA*/
23125c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT:
23225c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT:
23325c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT:
23425c76675SMarouene Boubakri res = set_tmem_param(¶ms[n].u.tmem, saved_attr[n],
23525c76675SMarouene Boubakri &ta_param->u[n].mem);
23625c76675SMarouene Boubakri if (res)
23725c76675SMarouene Boubakri return res;
23825c76675SMarouene Boubakri pt[n] = TEE_PARAM_TYPE_MEMREF_INPUT + attr -
23925c76675SMarouene Boubakri OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
24025c76675SMarouene Boubakri break;
24125c76675SMarouene Boubakri #ifdef CFG_CORE_DYN_SHM
24225c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT:
24325c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
24425c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT:
24525c76675SMarouene Boubakri res = set_rmem_param(¶ms[n].u.rmem,
24625c76675SMarouene Boubakri &ta_param->u[n].mem);
24725c76675SMarouene Boubakri if (res)
24825c76675SMarouene Boubakri return res;
24925c76675SMarouene Boubakri pt[n] = TEE_PARAM_TYPE_MEMREF_INPUT + attr -
25025c76675SMarouene Boubakri OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
25125c76675SMarouene Boubakri break;
25225c76675SMarouene Boubakri #endif /*CFG_CORE_DYN_SHM*/
25325c76675SMarouene Boubakri #endif /*!CFG_CORE_FFA*/
25425c76675SMarouene Boubakri default:
25525c76675SMarouene Boubakri return TEE_ERROR_BAD_PARAMETERS;
25625c76675SMarouene Boubakri }
25725c76675SMarouene Boubakri }
25825c76675SMarouene Boubakri
25925c76675SMarouene Boubakri ta_param->types = TEE_PARAM_TYPES(pt[0], pt[1], pt[2], pt[3]);
26025c76675SMarouene Boubakri
26125c76675SMarouene Boubakri return TEE_SUCCESS;
26225c76675SMarouene Boubakri }
26325c76675SMarouene Boubakri
cleanup_shm_refs(const uint64_t * saved_attr,struct tee_ta_param * param,uint32_t num_params)26425c76675SMarouene Boubakri static void cleanup_shm_refs(const uint64_t *saved_attr,
26525c76675SMarouene Boubakri struct tee_ta_param *param, uint32_t num_params)
26625c76675SMarouene Boubakri {
26725c76675SMarouene Boubakri size_t n;
26825c76675SMarouene Boubakri
269728616b2SJens Wiklander for (n = 0; n < MIN((unsigned int)TEE_NUM_PARAMS, num_params); n++) {
27025c76675SMarouene Boubakri switch (saved_attr[n]) {
27125c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT:
27225c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT:
27325c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT:
27425c76675SMarouene Boubakri #ifdef CFG_CORE_DYN_SHM
27525c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT:
27625c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
27725c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT:
27825c76675SMarouene Boubakri #endif
27925c76675SMarouene Boubakri mobj_put(param->u[n].mem.mobj);
28025c76675SMarouene Boubakri break;
28125c76675SMarouene Boubakri default:
28225c76675SMarouene Boubakri break;
28325c76675SMarouene Boubakri }
28425c76675SMarouene Boubakri }
28525c76675SMarouene Boubakri }
28625c76675SMarouene Boubakri
copy_out_param(struct tee_ta_param * ta_param,uint32_t num_params,struct optee_msg_param * params,uint64_t * saved_attr)28725c76675SMarouene Boubakri static void copy_out_param(struct tee_ta_param *ta_param, uint32_t num_params,
28825c76675SMarouene Boubakri struct optee_msg_param *params, uint64_t *saved_attr)
28925c76675SMarouene Boubakri {
29025c76675SMarouene Boubakri size_t n;
29125c76675SMarouene Boubakri
29225c76675SMarouene Boubakri for (n = 0; n < num_params; n++) {
29325c76675SMarouene Boubakri switch (TEE_PARAM_TYPE_GET(ta_param->types, n)) {
29425c76675SMarouene Boubakri case TEE_PARAM_TYPE_MEMREF_OUTPUT:
29525c76675SMarouene Boubakri case TEE_PARAM_TYPE_MEMREF_INOUT:
29625c76675SMarouene Boubakri switch (saved_attr[n] & OPTEE_MSG_ATTR_TYPE_MASK) {
29725c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT:
29825c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT:
29925c76675SMarouene Boubakri params[n].u.tmem.size = ta_param->u[n].mem.size;
30025c76675SMarouene Boubakri break;
30125c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
30225c76675SMarouene Boubakri case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT:
30325c76675SMarouene Boubakri params[n].u.rmem.size = ta_param->u[n].mem.size;
30425c76675SMarouene Boubakri break;
30525c76675SMarouene Boubakri default:
30625c76675SMarouene Boubakri break;
30725c76675SMarouene Boubakri }
30825c76675SMarouene Boubakri break;
30925c76675SMarouene Boubakri case TEE_PARAM_TYPE_VALUE_OUTPUT:
31025c76675SMarouene Boubakri case TEE_PARAM_TYPE_VALUE_INOUT:
31125c76675SMarouene Boubakri params[n].u.value.a = ta_param->u[n].val.a;
31225c76675SMarouene Boubakri params[n].u.value.b = ta_param->u[n].val.b;
31325c76675SMarouene Boubakri break;
31425c76675SMarouene Boubakri default:
31525c76675SMarouene Boubakri break;
31625c76675SMarouene Boubakri }
31725c76675SMarouene Boubakri }
31825c76675SMarouene Boubakri }
31925c76675SMarouene Boubakri
32025c76675SMarouene Boubakri /*
32125c76675SMarouene Boubakri * Extracts mandatory parameter for open session.
32225c76675SMarouene Boubakri *
32325c76675SMarouene Boubakri * Returns
32425c76675SMarouene Boubakri * false : mandatory parameter wasn't found or malformatted
32525c76675SMarouene Boubakri * true : paramater found and OK
32625c76675SMarouene Boubakri */
get_open_session_meta(size_t num_params,struct optee_msg_param * params,size_t * num_meta,TEE_UUID * uuid,TEE_Identity * clnt_id)32725c76675SMarouene Boubakri static TEE_Result get_open_session_meta(size_t num_params,
32825c76675SMarouene Boubakri struct optee_msg_param *params,
32925c76675SMarouene Boubakri size_t *num_meta, TEE_UUID *uuid,
33025c76675SMarouene Boubakri TEE_Identity *clnt_id)
33125c76675SMarouene Boubakri {
33225c76675SMarouene Boubakri const uint32_t req_attr = OPTEE_MSG_ATTR_META |
33325c76675SMarouene Boubakri OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
33425c76675SMarouene Boubakri
33525c76675SMarouene Boubakri if (num_params < 2)
33625c76675SMarouene Boubakri return TEE_ERROR_BAD_PARAMETERS;
33725c76675SMarouene Boubakri
33825c76675SMarouene Boubakri if (params[0].attr != req_attr || params[1].attr != req_attr)
33925c76675SMarouene Boubakri return TEE_ERROR_BAD_PARAMETERS;
34025c76675SMarouene Boubakri
34125c76675SMarouene Boubakri tee_uuid_from_octets(uuid, (void *)¶ms[0].u.value);
34225c76675SMarouene Boubakri clnt_id->login = params[1].u.value.c;
34325c76675SMarouene Boubakri switch (clnt_id->login) {
34425c76675SMarouene Boubakri case TEE_LOGIN_PUBLIC:
34525c76675SMarouene Boubakri case TEE_LOGIN_REE_KERNEL:
34625c76675SMarouene Boubakri memset(&clnt_id->uuid, 0, sizeof(clnt_id->uuid));
34725c76675SMarouene Boubakri break;
34825c76675SMarouene Boubakri case TEE_LOGIN_USER:
34925c76675SMarouene Boubakri case TEE_LOGIN_GROUP:
35025c76675SMarouene Boubakri case TEE_LOGIN_APPLICATION:
35125c76675SMarouene Boubakri case TEE_LOGIN_APPLICATION_USER:
35225c76675SMarouene Boubakri case TEE_LOGIN_APPLICATION_GROUP:
35325c76675SMarouene Boubakri tee_uuid_from_octets(&clnt_id->uuid,
35425c76675SMarouene Boubakri (void *)¶ms[1].u.value);
35525c76675SMarouene Boubakri break;
35625c76675SMarouene Boubakri default:
35725c76675SMarouene Boubakri return TEE_ERROR_BAD_PARAMETERS;
35825c76675SMarouene Boubakri }
35925c76675SMarouene Boubakri
36025c76675SMarouene Boubakri *num_meta = 2;
36125c76675SMarouene Boubakri return TEE_SUCCESS;
36225c76675SMarouene Boubakri }
36325c76675SMarouene Boubakri
entry_open_session(struct optee_msg_arg * arg,uint32_t num_params)36425c76675SMarouene Boubakri static void entry_open_session(struct optee_msg_arg *arg, uint32_t num_params)
36525c76675SMarouene Boubakri {
366d24c41efSClement Faure TEE_Result res = TEE_ERROR_GENERIC;
36725c76675SMarouene Boubakri TEE_ErrorOrigin err_orig = TEE_ORIGIN_TEE;
36825c76675SMarouene Boubakri struct tee_ta_session *s = NULL;
369d24c41efSClement Faure TEE_Identity clnt_id = { };
370d24c41efSClement Faure TEE_UUID uuid = { };
37185a3e2d5SClement Faure struct tee_ta_param param = { };
372d24c41efSClement Faure size_t num_meta = 0;
37325c76675SMarouene Boubakri uint64_t saved_attr[TEE_NUM_PARAMS] = { 0 };
37425c76675SMarouene Boubakri
37525c76675SMarouene Boubakri res = get_open_session_meta(num_params, arg->params, &num_meta, &uuid,
37625c76675SMarouene Boubakri &clnt_id);
37725c76675SMarouene Boubakri if (res != TEE_SUCCESS)
37825c76675SMarouene Boubakri goto out;
37925c76675SMarouene Boubakri
38025c76675SMarouene Boubakri res = copy_in_params(arg->params + num_meta, num_params - num_meta,
38125c76675SMarouene Boubakri ¶m, saved_attr);
38225c76675SMarouene Boubakri if (res != TEE_SUCCESS)
38325c76675SMarouene Boubakri goto cleanup_shm_refs;
38425c76675SMarouene Boubakri
38525c76675SMarouene Boubakri res = tee_ta_open_session(&err_orig, &s, &tee_open_sessions, &uuid,
38625c76675SMarouene Boubakri &clnt_id, TEE_TIMEOUT_INFINITE, ¶m);
38725c76675SMarouene Boubakri if (res != TEE_SUCCESS)
38825c76675SMarouene Boubakri s = NULL;
38925c76675SMarouene Boubakri copy_out_param(¶m, num_params - num_meta, arg->params + num_meta,
39025c76675SMarouene Boubakri saved_attr);
39125c76675SMarouene Boubakri
39225c76675SMarouene Boubakri /*
39325c76675SMarouene Boubakri * The occurrence of open/close session command is usually
39425c76675SMarouene Boubakri * un-predictable, using this property to increase randomness
39525c76675SMarouene Boubakri * of prng
39625c76675SMarouene Boubakri */
39725c76675SMarouene Boubakri plat_prng_add_jitter_entropy(CRYPTO_RNG_SRC_JITTER_SESSION,
39825c76675SMarouene Boubakri &session_pnum);
39925c76675SMarouene Boubakri
40025c76675SMarouene Boubakri cleanup_shm_refs:
40125c76675SMarouene Boubakri cleanup_shm_refs(saved_attr, ¶m, num_params - num_meta);
40225c76675SMarouene Boubakri
40325c76675SMarouene Boubakri out:
40425c76675SMarouene Boubakri if (s)
40525c76675SMarouene Boubakri arg->session = s->id;
40625c76675SMarouene Boubakri else
40725c76675SMarouene Boubakri arg->session = 0;
40825c76675SMarouene Boubakri arg->ret = res;
40925c76675SMarouene Boubakri arg->ret_origin = err_orig;
41025c76675SMarouene Boubakri }
41125c76675SMarouene Boubakri
entry_close_session(struct optee_msg_arg * arg,uint32_t num_params)41225c76675SMarouene Boubakri static void entry_close_session(struct optee_msg_arg *arg, uint32_t num_params)
41325c76675SMarouene Boubakri {
41425c76675SMarouene Boubakri TEE_Result res;
41525c76675SMarouene Boubakri struct tee_ta_session *s;
41625c76675SMarouene Boubakri
41725c76675SMarouene Boubakri if (num_params) {
41825c76675SMarouene Boubakri res = TEE_ERROR_BAD_PARAMETERS;
41925c76675SMarouene Boubakri goto out;
42025c76675SMarouene Boubakri }
42125c76675SMarouene Boubakri
42225c76675SMarouene Boubakri plat_prng_add_jitter_entropy(CRYPTO_RNG_SRC_JITTER_SESSION,
42325c76675SMarouene Boubakri &session_pnum);
42425c76675SMarouene Boubakri
42525c76675SMarouene Boubakri s = tee_ta_find_session(arg->session, &tee_open_sessions);
42625c76675SMarouene Boubakri res = tee_ta_close_session(s, &tee_open_sessions, NSAPP_IDENTITY);
42725c76675SMarouene Boubakri out:
42825c76675SMarouene Boubakri arg->ret = res;
42925c76675SMarouene Boubakri arg->ret_origin = TEE_ORIGIN_TEE;
43025c76675SMarouene Boubakri }
43125c76675SMarouene Boubakri
entry_invoke_command(struct optee_msg_arg * arg,uint32_t num_params)43225c76675SMarouene Boubakri static void entry_invoke_command(struct optee_msg_arg *arg, uint32_t num_params)
43325c76675SMarouene Boubakri {
43425c76675SMarouene Boubakri TEE_Result res;
43525c76675SMarouene Boubakri TEE_ErrorOrigin err_orig = TEE_ORIGIN_TEE;
43625c76675SMarouene Boubakri struct tee_ta_session *s;
43725c76675SMarouene Boubakri struct tee_ta_param param = { 0 };
43825c76675SMarouene Boubakri uint64_t saved_attr[TEE_NUM_PARAMS] = { 0 };
43925c76675SMarouene Boubakri
44025c76675SMarouene Boubakri res = copy_in_params(arg->params, num_params, ¶m, saved_attr);
44125c76675SMarouene Boubakri if (res != TEE_SUCCESS)
44225c76675SMarouene Boubakri goto out;
44325c76675SMarouene Boubakri
44425c76675SMarouene Boubakri s = tee_ta_get_session(arg->session, true, &tee_open_sessions);
44525c76675SMarouene Boubakri if (!s) {
44625c76675SMarouene Boubakri res = TEE_ERROR_BAD_PARAMETERS;
44725c76675SMarouene Boubakri goto out;
44825c76675SMarouene Boubakri }
44925c76675SMarouene Boubakri
45025c76675SMarouene Boubakri res = tee_ta_invoke_command(&err_orig, s, NSAPP_IDENTITY,
45125c76675SMarouene Boubakri TEE_TIMEOUT_INFINITE, arg->func, ¶m);
45225c76675SMarouene Boubakri
45325c76675SMarouene Boubakri tee_ta_put_session(s);
45425c76675SMarouene Boubakri
45525c76675SMarouene Boubakri copy_out_param(¶m, num_params, arg->params, saved_attr);
45625c76675SMarouene Boubakri
45725c76675SMarouene Boubakri out:
45825c76675SMarouene Boubakri cleanup_shm_refs(saved_attr, ¶m, num_params);
45925c76675SMarouene Boubakri
46025c76675SMarouene Boubakri arg->ret = res;
46125c76675SMarouene Boubakri arg->ret_origin = err_orig;
46225c76675SMarouene Boubakri }
46325c76675SMarouene Boubakri
entry_cancel(struct optee_msg_arg * arg,uint32_t num_params)46425c76675SMarouene Boubakri static void entry_cancel(struct optee_msg_arg *arg, uint32_t num_params)
46525c76675SMarouene Boubakri {
46625c76675SMarouene Boubakri TEE_Result res;
46725c76675SMarouene Boubakri TEE_ErrorOrigin err_orig = TEE_ORIGIN_TEE;
46825c76675SMarouene Boubakri struct tee_ta_session *s;
46925c76675SMarouene Boubakri
47025c76675SMarouene Boubakri if (num_params) {
47125c76675SMarouene Boubakri res = TEE_ERROR_BAD_PARAMETERS;
47225c76675SMarouene Boubakri goto out;
47325c76675SMarouene Boubakri }
47425c76675SMarouene Boubakri
47525c76675SMarouene Boubakri s = tee_ta_get_session(arg->session, false, &tee_open_sessions);
47625c76675SMarouene Boubakri if (!s) {
47725c76675SMarouene Boubakri res = TEE_ERROR_BAD_PARAMETERS;
47825c76675SMarouene Boubakri goto out;
47925c76675SMarouene Boubakri }
48025c76675SMarouene Boubakri
48125c76675SMarouene Boubakri res = tee_ta_cancel_command(&err_orig, s, NSAPP_IDENTITY);
48225c76675SMarouene Boubakri tee_ta_put_session(s);
48325c76675SMarouene Boubakri
48425c76675SMarouene Boubakri out:
48525c76675SMarouene Boubakri arg->ret = res;
48625c76675SMarouene Boubakri arg->ret_origin = err_orig;
48725c76675SMarouene Boubakri }
48825c76675SMarouene Boubakri
48925c76675SMarouene Boubakri #ifndef CFG_CORE_FFA
49025c76675SMarouene Boubakri #ifdef CFG_CORE_DYN_SHM
register_shm(struct optee_msg_arg * arg,uint32_t num_params)49125c76675SMarouene Boubakri static void register_shm(struct optee_msg_arg *arg, uint32_t num_params)
49225c76675SMarouene Boubakri {
493b259cc96SJens Wiklander struct optee_msg_param_tmem *tmem = NULL;
494b259cc96SJens Wiklander struct mobj *mobj = NULL;
495b259cc96SJens Wiklander
49625c76675SMarouene Boubakri arg->ret = TEE_ERROR_BAD_PARAMETERS;
49725c76675SMarouene Boubakri
49825c76675SMarouene Boubakri if (num_params != 1 ||
49925c76675SMarouene Boubakri (arg->params[0].attr !=
50025c76675SMarouene Boubakri (OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT | OPTEE_MSG_ATTR_NONCONTIG)))
50125c76675SMarouene Boubakri return;
50225c76675SMarouene Boubakri
503b259cc96SJens Wiklander tmem = &arg->params[0].u.tmem;
504b259cc96SJens Wiklander mobj = msg_param_mobj_from_noncontig(tmem->buf_ptr, tmem->size,
50525c76675SMarouene Boubakri tmem->shm_ref, false);
50625c76675SMarouene Boubakri
50725c76675SMarouene Boubakri if (!mobj)
50825c76675SMarouene Boubakri return;
50925c76675SMarouene Boubakri
51025c76675SMarouene Boubakri mobj_reg_shm_unguard(mobj);
51125c76675SMarouene Boubakri arg->ret = TEE_SUCCESS;
51225c76675SMarouene Boubakri }
51325c76675SMarouene Boubakri
unregister_shm(struct optee_msg_arg * arg,uint32_t num_params)51425c76675SMarouene Boubakri static void unregister_shm(struct optee_msg_arg *arg, uint32_t num_params)
51525c76675SMarouene Boubakri {
51625c76675SMarouene Boubakri if (num_params == 1) {
51725c76675SMarouene Boubakri uint64_t cookie = arg->params[0].u.rmem.shm_ref;
51825c76675SMarouene Boubakri TEE_Result res = mobj_reg_shm_release_by_cookie(cookie);
51925c76675SMarouene Boubakri
52025c76675SMarouene Boubakri if (res)
52125c76675SMarouene Boubakri EMSG("Can't find mapping with given cookie");
52225c76675SMarouene Boubakri arg->ret = res;
52325c76675SMarouene Boubakri } else {
52425c76675SMarouene Boubakri arg->ret = TEE_ERROR_BAD_PARAMETERS;
52525c76675SMarouene Boubakri arg->ret_origin = TEE_ORIGIN_TEE;
52625c76675SMarouene Boubakri }
52725c76675SMarouene Boubakri }
52825c76675SMarouene Boubakri #endif /*CFG_CORE_DYN_SHM*/
52925c76675SMarouene Boubakri #endif
53025c76675SMarouene Boubakri
lend_protmem(struct optee_msg_arg * arg,uint32_t num_params)531*00338334SJens Wiklander static void __maybe_unused lend_protmem(struct optee_msg_arg *arg,
532*00338334SJens Wiklander uint32_t num_params)
533*00338334SJens Wiklander {
534*00338334SJens Wiklander TEE_Result res = TEE_ERROR_BAD_PARAMETERS;
535*00338334SJens Wiklander struct optee_msg_param_tmem *tmem = NULL;
536*00338334SJens Wiklander struct mobj *mobj = NULL;
537*00338334SJens Wiklander uint64_t use_case = 0;
538*00338334SJens Wiklander uint64_t cookie = 0;
539*00338334SJens Wiklander paddr_size_t sz = 0;
540*00338334SJens Wiklander paddr_t pa = 0;
541*00338334SJens Wiklander
542*00338334SJens Wiklander if (num_params != 2 ||
543*00338334SJens Wiklander READ_ONCE(arg->params[0].attr) != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT ||
544*00338334SJens Wiklander READ_ONCE(arg->params[1].attr) != OPTEE_MSG_ATTR_TYPE_TMEM_INPUT)
545*00338334SJens Wiklander goto out;
546*00338334SJens Wiklander
547*00338334SJens Wiklander use_case = READ_ONCE(arg->params[0].u.value.a);
548*00338334SJens Wiklander tmem = &arg->params[1].u.tmem;
549*00338334SJens Wiklander cookie = READ_ONCE(tmem->shm_ref);
550*00338334SJens Wiklander pa = READ_ONCE(tmem->buf_ptr);
551*00338334SJens Wiklander sz = READ_ONCE(tmem->size);
552*00338334SJens Wiklander
553*00338334SJens Wiklander switch (use_case) {
554*00338334SJens Wiklander case MOBJ_USE_CASE_SEC_VIDEO_PLAY:
555*00338334SJens Wiklander case MOBJ_USE_CASE_TRUSED_UI:
556*00338334SJens Wiklander break;
557*00338334SJens Wiklander default:
558*00338334SJens Wiklander goto out;
559*00338334SJens Wiklander }
560*00338334SJens Wiklander mobj = mobj_protmem_alloc(pa, sz, cookie, use_case);
561*00338334SJens Wiklander if (mobj)
562*00338334SJens Wiklander res = TEE_SUCCESS;
563*00338334SJens Wiklander out:
564*00338334SJens Wiklander arg->ret = res;
565*00338334SJens Wiklander }
566*00338334SJens Wiklander
assign_protmem(struct optee_msg_arg * arg,uint32_t num_params)567*00338334SJens Wiklander static void __maybe_unused assign_protmem(struct optee_msg_arg *arg,
568*00338334SJens Wiklander uint32_t num_params)
569*00338334SJens Wiklander {
570*00338334SJens Wiklander TEE_Result res = TEE_ERROR_BAD_PARAMETERS;
571*00338334SJens Wiklander uint64_t use_case = 0;
572*00338334SJens Wiklander uint64_t cookie = 0;
573*00338334SJens Wiklander
574*00338334SJens Wiklander if (num_params != 1 ||
575*00338334SJens Wiklander READ_ONCE(arg->params[0].attr) != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT)
576*00338334SJens Wiklander goto out;
577*00338334SJens Wiklander
578*00338334SJens Wiklander cookie = READ_ONCE(arg->params[0].u.value.a);
579*00338334SJens Wiklander use_case = READ_ONCE(arg->params[0].u.value.b);
580*00338334SJens Wiklander res = mobj_ffa_assign_protmem(cookie, use_case);
581*00338334SJens Wiklander out:
582*00338334SJens Wiklander arg->ret = res;
583*00338334SJens Wiklander }
584*00338334SJens Wiklander
reclaim_protmem(struct optee_msg_arg * arg,uint32_t num_params)585*00338334SJens Wiklander static void __maybe_unused reclaim_protmem(struct optee_msg_arg *arg,
586*00338334SJens Wiklander uint32_t num_params)
587*00338334SJens Wiklander {
588*00338334SJens Wiklander if (num_params == 1 &&
589*00338334SJens Wiklander READ_ONCE(arg->params[0].attr) == OPTEE_MSG_ATTR_TYPE_RMEM_INPUT) {
590*00338334SJens Wiklander uint64_t cookie = READ_ONCE(arg->params[0].u.rmem.shm_ref);
591*00338334SJens Wiklander TEE_Result res = mobj_protmem_release_by_cookie(cookie);
592*00338334SJens Wiklander
593*00338334SJens Wiklander if (res)
594*00338334SJens Wiklander EMSG("Can't find mapping with cookie %#"PRIx64,
595*00338334SJens Wiklander cookie);
596*00338334SJens Wiklander arg->ret = res;
597*00338334SJens Wiklander } else {
598*00338334SJens Wiklander arg->ret = TEE_ERROR_BAD_PARAMETERS;
599*00338334SJens Wiklander arg->ret_origin = TEE_ORIGIN_TEE;
600*00338334SJens Wiklander }
601*00338334SJens Wiklander }
602*00338334SJens Wiklander
get_protmem_config(struct optee_msg_arg * arg,uint32_t num_params)603*00338334SJens Wiklander static void __maybe_unused get_protmem_config(struct optee_msg_arg *arg,
604*00338334SJens Wiklander uint32_t num_params)
605*00338334SJens Wiklander {
606*00338334SJens Wiklander uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INOUT,
607*00338334SJens Wiklander TEE_PARAM_TYPE_MEMREF_OUTPUT,
608*00338334SJens Wiklander TEE_PARAM_TYPE_NONE,
609*00338334SJens Wiklander TEE_PARAM_TYPE_NONE);
610*00338334SJens Wiklander uint64_t saved_attr[TEE_NUM_PARAMS] = { 0 };
611*00338334SJens Wiklander TEE_Result res = TEE_ERROR_BAD_PARAMETERS;
612*00338334SJens Wiklander struct tee_ta_param param = { 0 };
613*00338334SJens Wiklander size_t min_mem_align = 0;
614*00338334SJens Wiklander size_t min_mem_sz = 0;
615*00338334SJens Wiklander uint64_t use_case = 0;
616*00338334SJens Wiklander void *buf = NULL;
617*00338334SJens Wiklander size_t sz = 0;
618*00338334SJens Wiklander
619*00338334SJens Wiklander arg->ret_origin = TEE_ORIGIN_TEE;
620*00338334SJens Wiklander
621*00338334SJens Wiklander if (num_params != 2)
622*00338334SJens Wiklander goto out;
623*00338334SJens Wiklander res = copy_in_params(arg->params, num_params, ¶m, saved_attr);
624*00338334SJens Wiklander if (res)
625*00338334SJens Wiklander goto out;
626*00338334SJens Wiklander if (param.types != exp_pt) {
627*00338334SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS;
628*00338334SJens Wiklander goto out_cleanup;
629*00338334SJens Wiklander }
630*00338334SJens Wiklander
631*00338334SJens Wiklander use_case = param.u[0].val.a;
632*00338334SJens Wiklander /* Check that it's not truncated when passed as an enum */
633*00338334SJens Wiklander if (use_case >= INT_MAX) {
634*00338334SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS;
635*00338334SJens Wiklander goto out_cleanup;
636*00338334SJens Wiklander }
637*00338334SJens Wiklander sz = param.u[1].mem.size;
638*00338334SJens Wiklander if (param.u[1].mem.mobj) {
639*00338334SJens Wiklander res = mobj_inc_map(param.u[1].mem.mobj);
640*00338334SJens Wiklander if (res)
641*00338334SJens Wiklander goto out_cleanup;
642*00338334SJens Wiklander buf = mobj_get_va(param.u[1].mem.mobj, param.u[1].mem.offs, sz);
643*00338334SJens Wiklander if (!buf) {
644*00338334SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS;
645*00338334SJens Wiklander goto out_dec_map;
646*00338334SJens Wiklander }
647*00338334SJens Wiklander }
648*00338334SJens Wiklander
649*00338334SJens Wiklander if (IS_ENABLED(CFG_CORE_FFA)) {
650*00338334SJens Wiklander #ifdef CFG_CORE_FFA
651*00338334SJens Wiklander res = thread_spmc_get_protmem_config(use_case, buf, &sz,
652*00338334SJens Wiklander &min_mem_sz,
653*00338334SJens Wiklander &min_mem_align);
654*00338334SJens Wiklander #else
655*00338334SJens Wiklander res = TEE_ERROR_NOT_SUPPORTED;
656*00338334SJens Wiklander #endif
657*00338334SJens Wiklander } else {
658*00338334SJens Wiklander res = plat_get_protmem_config(use_case, &min_mem_sz,
659*00338334SJens Wiklander &min_mem_align);
660*00338334SJens Wiklander }
661*00338334SJens Wiklander if (!res || res == TEE_ERROR_SHORT_BUFFER) {
662*00338334SJens Wiklander param.u[1].mem.size = sz;
663*00338334SJens Wiklander param.u[0].val.a = min_mem_sz;
664*00338334SJens Wiklander param.u[0].val.b = min_mem_align;
665*00338334SJens Wiklander }
666*00338334SJens Wiklander copy_out_param(¶m, num_params, arg->params, saved_attr);
667*00338334SJens Wiklander arg->params[0].u.value.c = sizeof(long) * 8;
668*00338334SJens Wiklander
669*00338334SJens Wiklander out_dec_map:
670*00338334SJens Wiklander mobj_dec_map(param.u[1].mem.mobj);
671*00338334SJens Wiklander out_cleanup:
672*00338334SJens Wiklander cleanup_shm_refs(saved_attr, ¶m, num_params);
673*00338334SJens Wiklander out:
674*00338334SJens Wiklander arg->ret = res;
675*00338334SJens Wiklander }
676*00338334SJens Wiklander
nsec_sessions_list_head(struct tee_ta_session_head ** open_sessions)67725c76675SMarouene Boubakri void nsec_sessions_list_head(struct tee_ta_session_head **open_sessions)
67825c76675SMarouene Boubakri {
67925c76675SMarouene Boubakri *open_sessions = &tee_open_sessions;
68025c76675SMarouene Boubakri }
68125c76675SMarouene Boubakri
68225c76675SMarouene Boubakri /* Note: this function is weak to let platforms add special handling */
tee_entry_std(struct optee_msg_arg * arg,uint32_t num_params)683453d8327SJens Wiklander TEE_Result __weak tee_entry_std(struct optee_msg_arg *arg, uint32_t num_params)
68425c76675SMarouene Boubakri {
68525c76675SMarouene Boubakri return __tee_entry_std(arg, num_params);
68625c76675SMarouene Boubakri }
68725c76675SMarouene Boubakri
68825c76675SMarouene Boubakri /*
68925c76675SMarouene Boubakri * If tee_entry_std() is overridden, it's still supposed to call this
69025c76675SMarouene Boubakri * function.
69125c76675SMarouene Boubakri */
__tee_entry_std(struct optee_msg_arg * arg,uint32_t num_params)692453d8327SJens Wiklander TEE_Result __tee_entry_std(struct optee_msg_arg *arg, uint32_t num_params)
69325c76675SMarouene Boubakri {
694453d8327SJens Wiklander TEE_Result res = TEE_SUCCESS;
69525c76675SMarouene Boubakri
69625c76675SMarouene Boubakri /* Enable foreign interrupts for STD calls */
69725c76675SMarouene Boubakri thread_set_foreign_intr(true);
69825c76675SMarouene Boubakri switch (arg->cmd) {
69925c76675SMarouene Boubakri case OPTEE_MSG_CMD_OPEN_SESSION:
70025c76675SMarouene Boubakri entry_open_session(arg, num_params);
70125c76675SMarouene Boubakri break;
70225c76675SMarouene Boubakri case OPTEE_MSG_CMD_CLOSE_SESSION:
70325c76675SMarouene Boubakri entry_close_session(arg, num_params);
70425c76675SMarouene Boubakri break;
70525c76675SMarouene Boubakri case OPTEE_MSG_CMD_INVOKE_COMMAND:
70625c76675SMarouene Boubakri entry_invoke_command(arg, num_params);
70725c76675SMarouene Boubakri break;
70825c76675SMarouene Boubakri case OPTEE_MSG_CMD_CANCEL:
70925c76675SMarouene Boubakri entry_cancel(arg, num_params);
71025c76675SMarouene Boubakri break;
711*00338334SJens Wiklander #if defined(CFG_CORE_DYN_SHM) && !defined(CFG_CORE_FFA)
71225c76675SMarouene Boubakri case OPTEE_MSG_CMD_REGISTER_SHM:
71325c76675SMarouene Boubakri register_shm(arg, num_params);
71425c76675SMarouene Boubakri break;
71525c76675SMarouene Boubakri case OPTEE_MSG_CMD_UNREGISTER_SHM:
71625c76675SMarouene Boubakri unregister_shm(arg, num_params);
71725c76675SMarouene Boubakri break;
71825c76675SMarouene Boubakri #endif
719c2d44948SJens Wiklander case OPTEE_MSG_CMD_DO_BOTTOM_HALF:
720c2d44948SJens Wiklander if (IS_ENABLED(CFG_CORE_ASYNC_NOTIF))
721c2d44948SJens Wiklander notif_deliver_event(NOTIF_EVENT_DO_BOTTOM_HALF);
722c2d44948SJens Wiklander else
723c2d44948SJens Wiklander goto err;
724c2d44948SJens Wiklander break;
725c2d44948SJens Wiklander case OPTEE_MSG_CMD_STOP_ASYNC_NOTIF:
726c2d44948SJens Wiklander if (IS_ENABLED(CFG_CORE_ASYNC_NOTIF))
727c2d44948SJens Wiklander notif_deliver_event(NOTIF_EVENT_STOPPED);
728c2d44948SJens Wiklander else
729c2d44948SJens Wiklander goto err;
730c2d44948SJens Wiklander break;
731*00338334SJens Wiklander #ifdef CFG_CORE_DYN_PROTMEM
732*00338334SJens Wiklander case OPTEE_MSG_CMD_GET_PROTMEM_CONFIG:
733*00338334SJens Wiklander get_protmem_config(arg, num_params);
734*00338334SJens Wiklander break;
735*00338334SJens Wiklander #ifdef CFG_CORE_FFA
736*00338334SJens Wiklander case OPTEE_MSG_CMD_ASSIGN_PROTMEM:
737*00338334SJens Wiklander assign_protmem(arg, num_params);
738*00338334SJens Wiklander break;
739*00338334SJens Wiklander #else
740*00338334SJens Wiklander case OPTEE_MSG_CMD_LEND_PROTMEM:
741*00338334SJens Wiklander lend_protmem(arg, num_params);
742*00338334SJens Wiklander break;
743*00338334SJens Wiklander case OPTEE_MSG_CMD_RECLAIM_PROTMEM:
744*00338334SJens Wiklander reclaim_protmem(arg, num_params);
745*00338334SJens Wiklander break;
746*00338334SJens Wiklander #endif /*!CFG_CORE_FFA*/
747*00338334SJens Wiklander #endif /*CFG_CORE_DYN_PROTMEM*/
74825c76675SMarouene Boubakri default:
749c2d44948SJens Wiklander err:
75025c76675SMarouene Boubakri EMSG("Unknown cmd 0x%x", arg->cmd);
751453d8327SJens Wiklander res = TEE_ERROR_NOT_IMPLEMENTED;
75225c76675SMarouene Boubakri }
75325c76675SMarouene Boubakri
754453d8327SJens Wiklander return res;
75525c76675SMarouene Boubakri }
75625c76675SMarouene Boubakri
default_mobj_init(void)75725c76675SMarouene Boubakri static TEE_Result default_mobj_init(void)
75825c76675SMarouene Boubakri {
75925c76675SMarouene Boubakri #ifdef CFG_CORE_RESERVED_SHM
76025c76675SMarouene Boubakri shm_mobj = mobj_phys_alloc(default_nsec_shm_paddr,
76125c76675SMarouene Boubakri default_nsec_shm_size, SHM_CACHE_ATTRS,
76225c76675SMarouene Boubakri CORE_MEM_NSEC_SHM);
76325c76675SMarouene Boubakri if (!shm_mobj)
76425c76675SMarouene Boubakri panic("Failed to register shared memory");
76525c76675SMarouene Boubakri #endif
76625c76675SMarouene Boubakri
76725c76675SMarouene Boubakri #ifdef CFG_SECURE_DATA_PATH
76825c76675SMarouene Boubakri sdp_mem_mobjs = core_sdp_mem_create_mobjs();
76925c76675SMarouene Boubakri if (!sdp_mem_mobjs)
77025c76675SMarouene Boubakri panic("Failed to register SDP memory");
77125c76675SMarouene Boubakri #endif
77225c76675SMarouene Boubakri
77325c76675SMarouene Boubakri return TEE_SUCCESS;
77425c76675SMarouene Boubakri }
77525c76675SMarouene Boubakri
77625c76675SMarouene Boubakri driver_init_late(default_mobj_init);
777