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