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 __KERNEL_TEE_TA_MANAGER_H
9 #define __KERNEL_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_initializing; /* Context initialization is not completed */
77 bool is_releasing; /* Context is about to be released */
78 struct condvar busy_cv; /* CV used when context is busy */
79 };
80
81 struct tee_ta_session {
82 TAILQ_ENTRY(tee_ta_session) link;
83 struct ts_session ts_sess;
84 uint32_t id; /* Session handle (0 is invalid) */
85 TEE_Identity clnt_id; /* Identify of client */
86 struct tee_ta_param *param;
87 TEE_ErrorOrigin err_origin;
88 bool cancel; /* True if TA invocation is cancelled */
89 bool cancel_mask; /* True if cancel is masked */
90 TEE_Time cancel_time; /* Time when to cancel the TA invocation */
91 uint32_t ref_count; /* reference counter */
92 struct condvar refc_cv; /* CV used to wait for ref_count to be 0 */
93 struct condvar lock_cv; /* CV used to wait for lock */
94 short int lock_thread; /* Id of thread holding the lock */
95 bool unlink; /* True if session is to be unlinked */
96 };
97
98 /* Registered contexts */
99 extern struct tee_ta_ctx_head tee_ctxes;
100
101 extern struct mutex tee_ta_mutex;
102 extern struct condvar tee_ta_init_cv;
103
104 TEE_Result tee_ta_open_session(TEE_ErrorOrigin *err,
105 struct tee_ta_session **sess,
106 struct tee_ta_session_head *open_sessions,
107 const TEE_UUID *uuid,
108 const TEE_Identity *clnt_id,
109 uint32_t cancel_req_to,
110 struct tee_ta_param *param);
111
112 TEE_Result tee_ta_invoke_command(TEE_ErrorOrigin *err,
113 struct tee_ta_session *sess,
114 const TEE_Identity *clnt_id,
115 uint32_t cancel_req_to, uint32_t cmd,
116 struct tee_ta_param *param);
117
118 TEE_Result tee_ta_cancel_command(TEE_ErrorOrigin *err,
119 struct tee_ta_session *sess,
120 const TEE_Identity *clnt_id);
121
122 bool tee_ta_session_is_cancelled(struct tee_ta_session *s, TEE_Time *curr_time);
123
124 /*-----------------------------------------------------------------------------
125 * Function called to close a TA.
126 * Parameters:
127 * id - The session id (in)
128 * Returns:
129 * TEE_Result
130 *---------------------------------------------------------------------------*/
131 TEE_Result tee_ta_close_session(struct tee_ta_session *sess,
132 struct tee_ta_session_head *open_sessions,
133 const TEE_Identity *clnt_id);
134
135
136
137 struct tee_ta_session *tee_ta_find_session(uint32_t id,
138 struct tee_ta_session_head *open_sessions);
139
140 struct tee_ta_session *tee_ta_get_session(uint32_t id, bool exclusive,
141 struct tee_ta_session_head *open_sessions);
142
143 void tee_ta_put_session(struct tee_ta_session *sess);
144
145 #if defined(CFG_TA_GPROF_SUPPORT)
146 void tee_ta_update_session_utime_suspend(void);
147 void tee_ta_update_session_utime_resume(void);
148 void tee_ta_gprof_sample_pc(vaddr_t pc);
149 #else
tee_ta_update_session_utime_suspend(void)150 static inline void tee_ta_update_session_utime_suspend(void) {}
tee_ta_update_session_utime_resume(void)151 static inline void tee_ta_update_session_utime_resume(void) {}
tee_ta_gprof_sample_pc(vaddr_t pc __unused)152 static inline void tee_ta_gprof_sample_pc(vaddr_t pc __unused) {}
153 #endif
154 #if defined(CFG_FTRACE_SUPPORT)
155 void tee_ta_ftrace_update_times_suspend(void);
156 void tee_ta_ftrace_update_times_resume(void);
157 #else
tee_ta_ftrace_update_times_suspend(void)158 static inline void tee_ta_ftrace_update_times_suspend(void) {}
tee_ta_ftrace_update_times_resume(void)159 static inline void tee_ta_ftrace_update_times_resume(void) {}
160 #endif
161
162 bool is_ta_ctx(struct ts_ctx *ctx);
163
164 struct tee_ta_session *to_ta_session(struct ts_session *sess);
165
to_ta_ctx(struct ts_ctx * ctx)166 static inline struct tee_ta_ctx *__noprof to_ta_ctx(struct ts_ctx *ctx)
167 {
168 assert(is_ta_ctx(ctx));
169 return container_of(ctx, struct tee_ta_ctx, ts_ctx);
170 }
171
172 #if defined(CFG_TA_STATS)
173 TEE_Result tee_ta_instance_stats(void *buff, size_t *buff_size);
174 #endif
175
176 #endif
177