1 /* SPDX-License-Identifier: BSD-2-Clause */ 2 /* 3 * Copyright (c) 2014, STMicroelectronics International N.V. 4 * Copyright (c) 2017, Linaro Limited 5 * Copyright (c) 2020, Arm Limited 6 */ 7 8 #ifndef TEE_TA_MANAGER_H 9 #define TEE_TA_MANAGER_H 10 11 #include <assert.h> 12 #include <kernel/mutex.h> 13 #include <kernel/tee_common.h> 14 #include <kernel/ts_manager.h> 15 #include <mm/tee_mmu_types.h> 16 #include <sys/queue.h> 17 #include <tee_api_types.h> 18 #include <types_ext.h> 19 #include <user_ta_header.h> 20 #include <utee_types.h> 21 22 /* Magic TEE identity pointer: set when teecore requests a TA close */ 23 #define KERN_IDENTITY ((TEE_Identity *)-1) 24 /* Operation is initiated by a client (non-secure) app */ 25 #define NSAPP_IDENTITY (NULL) 26 27 TAILQ_HEAD(tee_ta_session_head, tee_ta_session); 28 TAILQ_HEAD(tee_ta_ctx_head, tee_ta_ctx); 29 30 struct mobj; 31 32 struct param_val { 33 uint32_t a; 34 uint32_t b; 35 }; 36 37 struct param_mem { 38 struct mobj *mobj; 39 size_t size; 40 size_t offs; 41 }; 42 43 struct tee_ta_param { 44 uint32_t types; 45 union { 46 struct param_val val; 47 struct param_mem mem; 48 } u[TEE_NUM_PARAMS]; 49 }; 50 51 struct user_ta_ctx; 52 53 #if defined(CFG_TA_GPROF_SUPPORT) 54 struct sample_buf { 55 uint32_t nsamples; /* Size of @samples array in uint16_t */ 56 uint32_t offset; /* Passed from user mode */ 57 uint32_t scale; /* Passed from user mode */ 58 uint32_t count; /* Number of samples taken */ 59 bool enabled; /* Sampling enabled? */ 60 uint16_t *samples; 61 uint64_t usr; /* Total user CPU time for this session */ 62 uint64_t usr_entered; /* When this session last entered user mode */ 63 uint32_t freq; /* @usr divided by @freq is in seconds */ 64 }; 65 #endif 66 67 /* Context of a loaded TA */ 68 struct tee_ta_ctx { 69 uint32_t flags; /* TA_FLAGS from TA header */ 70 TAILQ_ENTRY(tee_ta_ctx) link; 71 struct ts_ctx ts_ctx; 72 uint32_t panicked; /* True if TA has panicked, written from asm */ 73 uint32_t panic_code; /* Code supplied for panic */ 74 uint32_t ref_count; /* Reference counter for multi session TA */ 75 bool busy; /* Context is busy and cannot be entered */ 76 bool is_releasing; /* Context is about to be released */ 77 struct condvar busy_cv; /* CV used when context is busy */ 78 }; 79 80 struct tee_ta_session { 81 TAILQ_ENTRY(tee_ta_session) link; 82 struct ts_session ts_sess; 83 uint32_t id; /* Session handle (0 is invalid) */ 84 TEE_Identity clnt_id; /* Identify of client */ 85 struct tee_ta_param *param; 86 TEE_ErrorOrigin err_origin; 87 bool cancel; /* True if TA invocation is cancelled */ 88 bool cancel_mask; /* True if cancel is masked */ 89 TEE_Time cancel_time; /* Time when to cancel the TA invocation */ 90 uint32_t ref_count; /* reference counter */ 91 struct condvar refc_cv; /* CV used to wait for ref_count to be 0 */ 92 struct condvar lock_cv; /* CV used to wait for lock */ 93 short int lock_thread; /* Id of thread holding the lock */ 94 bool unlink; /* True if session is to be unlinked */ 95 }; 96 97 /* Registered contexts */ 98 extern struct tee_ta_ctx_head tee_ctxes; 99 100 extern struct mutex tee_ta_mutex; 101 extern struct condvar tee_ta_init_cv; 102 103 TEE_Result tee_ta_open_session(TEE_ErrorOrigin *err, 104 struct tee_ta_session **sess, 105 struct tee_ta_session_head *open_sessions, 106 const TEE_UUID *uuid, 107 const TEE_Identity *clnt_id, 108 uint32_t cancel_req_to, 109 struct tee_ta_param *param); 110 111 TEE_Result tee_ta_invoke_command(TEE_ErrorOrigin *err, 112 struct tee_ta_session *sess, 113 const TEE_Identity *clnt_id, 114 uint32_t cancel_req_to, uint32_t cmd, 115 struct tee_ta_param *param); 116 117 TEE_Result tee_ta_cancel_command(TEE_ErrorOrigin *err, 118 struct tee_ta_session *sess, 119 const TEE_Identity *clnt_id); 120 121 bool tee_ta_session_is_cancelled(struct tee_ta_session *s, TEE_Time *curr_time); 122 123 /*----------------------------------------------------------------------------- 124 * Function called to close a TA. 125 * Parameters: 126 * id - The session id (in) 127 * Returns: 128 * TEE_Result 129 *---------------------------------------------------------------------------*/ 130 TEE_Result tee_ta_close_session(struct tee_ta_session *sess, 131 struct tee_ta_session_head *open_sessions, 132 const TEE_Identity *clnt_id); 133 134 135 136 struct tee_ta_session *tee_ta_find_session(uint32_t id, 137 struct tee_ta_session_head *open_sessions); 138 139 struct tee_ta_session *tee_ta_get_session(uint32_t id, bool exclusive, 140 struct tee_ta_session_head *open_sessions); 141 142 void tee_ta_put_session(struct tee_ta_session *sess); 143 144 #if defined(CFG_TA_GPROF_SUPPORT) 145 void tee_ta_update_session_utime_suspend(void); 146 void tee_ta_update_session_utime_resume(void); 147 void tee_ta_gprof_sample_pc(vaddr_t pc); 148 #else 149 static inline void tee_ta_update_session_utime_suspend(void) {} 150 static inline void tee_ta_update_session_utime_resume(void) {} 151 static inline void tee_ta_gprof_sample_pc(vaddr_t pc __unused) {} 152 #endif 153 #if defined(CFG_FTRACE_SUPPORT) 154 void tee_ta_ftrace_update_times_suspend(void); 155 void tee_ta_ftrace_update_times_resume(void); 156 #else 157 static inline void tee_ta_ftrace_update_times_suspend(void) {} 158 static inline void tee_ta_ftrace_update_times_resume(void) {} 159 #endif 160 161 bool is_ta_ctx(struct ts_ctx *ctx); 162 163 struct tee_ta_session *to_ta_session(struct ts_session *sess); 164 165 static inline struct tee_ta_ctx *to_ta_ctx(struct ts_ctx *ctx) 166 { 167 assert(is_ta_ctx(ctx)); 168 return container_of(ctx, struct tee_ta_ctx, ts_ctx); 169 } 170 171 #if defined(CFG_TA_STATS) 172 TEE_Result tee_ta_instance_stats(void *buff, size_t *buff_size); 173 #endif 174 175 #endif 176