1 /*
2 * Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved
3 * Copyright (c) 2013, Google, Inc. All rights reserved
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files
7 * (the "Software"), to deal in the Software without restriction,
8 * including without limitation the rights to use, copy, modify, merge,
9 * publish, distribute, sublicense, and/or sell copies of the Software,
10 * and to permit persons to whom the Software is furnished to do so,
11 * subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 #ifndef __LIB_TRUSTY_APP_H
26 #define __LIB_TRUSTY_APP_H
27
28 #include <assert.h>
29 #include <kernel/physmem.h>
30 #include <kernel/thread.h>
31 #include <kernel/usercopy.h>
32 #include <kernel/vm.h>
33 #include <lib/trusty/uuid.h>
34 #include <list.h>
35 #include <stdbool.h>
36 #include <sys/types.h>
37
38 /**
39 * SHA512 output size
40 */
41 #define HASH_SIZE_BYTES 64
42
43 enum app_state {
44 APP_NOT_RUNNING = 0,
45 APP_STARTING,
46 APP_RUNNING,
47 APP_TERMINATING,
48 APP_RESTARTING,
49 APP_FAILED_TO_START,
50 };
51
52 /**
53 * enum app_flags - Flags for Trusty applications
54 * @APP_FLAGS_LOADABLE: This is a loadable application.
55 * @APP_FLAGS_CREATION_MASK: Flags allowed during app creation.
56 */
57 enum app_flags {
58 APP_FLAGS_LOADABLE = (1 << 0),
59
60 APP_FLAGS_CREATION_MASK = APP_FLAGS_LOADABLE,
61 };
62
63 struct manifest_port_entry {
64 uint32_t flags;
65 uint32_t path_len;
66 /* Points to a string within an application's manifest blob */
67 const char* path;
68 struct list_node node;
69 };
70
71 struct manifest_mmio_entry {
72 struct list_node node;
73 struct phys_mem_obj phys_mem_obj;
74 struct obj_ref phys_mem_obj_self_ref;
75 uint32_t id;
76 };
77
78 struct trusty_app_props {
79 uuid_t uuid;
80 const char* app_name;
81 uint32_t mgmt_flags;
82 uint32_t min_stack_size;
83 uint32_t min_heap_size;
84 uint32_t min_shadow_stack_size;
85 uint32_t map_io_mem_cnt;
86 struct list_node port_entry_list;
87 struct list_node mmio_entry_list;
88 /* record paddrs mapped by prepare_dma until released by finish_dma */
89 struct list_node dma_entry_list;
90 int pinned_cpu;
91 int priority;
92 bool feature_bti;
93 };
94
95 struct trusty_app_img {
96 uintptr_t manifest_start;
97 uintptr_t manifest_end;
98 uintptr_t img_start;
99 uintptr_t img_end;
100 };
101
102 /**
103 * struct trusty_app_mmio_allowed_range - Allowed MMIO range for loadable apps.
104 * @node: Internal list node, should be initialized to
105 * %LIST_INITIAL_CLEARED_VALUE.
106 * @uuid: The UUID of this application.
107 * @start: Start address of this range.
108 * @size: Size of this range.
109 */
110 struct trusty_app_mmio_allowed_range {
111 struct list_node node;
112 uuid_t uuid;
113 paddr_t start;
114 size_t size;
115 };
116
117 #define TRUSTY_APP_MMIO_ALLOWED_RANGE(_name, _uuid, _start, _size) \
118 static struct trusty_app_mmio_allowed_range _name = { \
119 .node = LIST_INITIAL_CLEARED_VALUE, \
120 .uuid = _uuid, \
121 .start = (_start), \
122 .size = (_size), \
123 };
124
125 /**
126 * trusty_app_allow_mmio_range() - Add a new allowed MMIO range
127 * @range: Pointer to the range to add.
128 *
129 * Adds a memory mapping to the internal list of allowed memory ranges.
130 * The underlying structure will be added to a permanent linked list,
131 * so it must not be a temporary value, e.g., on the stack.
132 * The best option is to pass in a structure created with the
133 * %TRUSTY_APP_MMIO_ALLOWED_RANGE macro.
134 *
135 * This function should be called before any loadable app is started,
136 * e.g., at init level LK_INIT_LEVEL_APPS - 1.
137 */
138 void trusty_app_allow_mmio_range(struct trusty_app_mmio_allowed_range* range);
139
140 struct trusty_app;
141
142 struct trusty_thread {
143 vaddr_t stack_start;
144 size_t stack_size;
145 #if USER_SCS_SUPPORTED
146 vaddr_t shadow_stack_base;
147 size_t shadow_stack_size;
148 #endif
149 vaddr_t entry;
150 thread_t* thread;
151 struct trusty_app* app;
152 };
153
154 struct trusty_app {
155 /* corresponds to the order in which the apps were started */
156 u_int app_id;
157 enum app_state state;
158 uint32_t flags;
159 lk_time_ns_t min_start_time;
160 vmm_aspace_t* aspace;
161 bool used_brk;
162 vaddr_t start_brk;
163 vaddr_t cur_brk;
164 vaddr_t end_brk;
165 vaddr_t load_bias;
166 struct trusty_app_props props;
167 struct trusty_app_img app_img;
168 struct trusty_thread* thread;
169 /* app local storage */
170 void** als;
171 struct list_node node;
172 };
173
174 void trusty_app_init(void);
175
176 /**
177 * trusty_app_create_and_start() - Create and start a new Trusty application
178 * @app_img: metadata of the application to load.
179 * @flags: Creation flags, values from &enum app_flags.
180 *
181 * Return: ERR_NO_MEMORY if out of memory, ERR_NOT_VALID if
182 * the application ELF or manifest are not valid.
183 */
184 status_t trusty_app_create_and_start(struct trusty_app_img* app_img,
185 uint32_t flags);
186
187 /**
188 * trusty_app_is_startup_port() - Query if the specified port is a startup port
189 * @port_path: path of the port to check.
190 *
191 * Return: true if @port_path has been registered as a startup port by an
192 * application, false otherwise.
193 */
194 bool trusty_app_is_startup_port(const char* port_path);
195
196 /**
197 * trusty_app_request_start_by_port() - Request that the application (if any)
198 * that has registered the given port be started.
199 * @port_path: path of the registered port.
200 * @uuid: uuid of the application triggering the request.
201 *
202 * If the application is already running then this function has no effect.
203 * Otherwise the application will be started.
204 *
205 * Return: ERR_NOT_FOUND if no application has registered @port_path or if the
206 * port is not accessible to @uuid, ERR_ALREADY_STARTED
207 * if the application is already running, ERR_CANCELLED if the application
208 * failed to start, or NO_ERROR otherwise.
209 */
210 status_t trusty_app_request_start_by_port(const char* port_path,
211 const uuid_t* uuid);
212
213 void trusty_app_exit(int status) __NO_RETURN;
214 void trusty_app_crash(uint32_t reason, uint64_t far, uint64_t elr) __NO_RETURN;
215 status_t trusty_app_setup_mmio(struct trusty_app* trusty_app,
216 uint32_t mmio_id,
217 user_addr_t* uaddr_p,
218 uint32_t size);
219 void trusty_app_forall(void (*fn)(struct trusty_app* ta, void* data),
220 void* data);
221 void trusty_thread_exit(int status);
222
223 struct trusty_error_args {
224 uint32_t reason;
225 bool is_crash;
226 uint64_t far;
227 uint8_t far_hash[HASH_SIZE_BYTES];
228 uint64_t elr;
229 uint8_t elr_hash[HASH_SIZE_BYTES];
230 bool is_hash;
231 };
232
233 struct trusty_app_notifier {
234 struct list_node node;
235 status_t (*startup)(struct trusty_app* app);
236 status_t (*shutdown)(struct trusty_app* app);
237 status_t (*crash)(struct trusty_app* app, const struct trusty_error_args* error_args);
238 };
239
240 /*
241 * All app notifiers registration has to be complete before
242 * libtrusty is initialized which is happening at LK_INIT_LEVEL_APPS-1
243 * init level.
244 */
245 status_t trusty_register_app_notifier(struct trusty_app_notifier* n);
246
247 /*
248 * All als slots must be allocated before libtrusty is initialized
249 * which is happening at LK_INIT_LEVEL_APPS-1 init level.
250 */
251 int trusty_als_alloc_slot(void);
252
253 extern uint als_slot_cnt;
254
trusty_als_get(struct trusty_app * app,int slot_id)255 static inline void* trusty_als_get(struct trusty_app* app, int slot_id) {
256 uint slot = slot_id - 1;
257 ASSERT(slot < als_slot_cnt);
258 return app->als[slot];
259 }
260
trusty_als_set(struct trusty_app * app,int slot_id,void * ptr)261 static inline void trusty_als_set(struct trusty_app* app,
262 int slot_id,
263 void* ptr) {
264 uint slot = slot_id - 1;
265 ASSERT(slot < als_slot_cnt);
266 app->als[slot] = ptr;
267 }
268
trusty_thread_get(thread_t * t)269 static inline struct trusty_thread* trusty_thread_get(thread_t* t) {
270 return (struct trusty_thread*)thread_tls_get(t, TLS_ENTRY_TRUSTY);
271 }
272
current_trusty_thread(void)273 static inline struct trusty_thread* current_trusty_thread(void) {
274 return (struct trusty_thread*)tls_get(TLS_ENTRY_TRUSTY);
275 }
276
current_trusty_app(void)277 static inline struct trusty_app* current_trusty_app(void) {
278 struct trusty_thread* trusty_thread = current_trusty_thread();
279 if (!trusty_thread) {
280 return NULL;
281 }
282 return trusty_thread->app;
283 }
284
285 /**
286 * trusty_app_allow_dma_range() - Mark dma range as allowed.
287 * @app: app which should be allowed to use dma range
288 * @obj: backing object for the dma range being allowed
289 * @offset: offset into the backing object
290 * @size: size of the dma range in bytes
291 * @vaddr: virtual memory address. Used to tear down all mappings from a single
292 * call to prepare_dma
293 * @flags: flags used to map dma range
294 *
295 * Return: ERR_INVALID_ARGS if range has already been mapped, ERR_NO_MEMORY if
296 * allocation of the bookkeeping structure failed, and NO_ERROR
297 * otherwise.
298 */
299 status_t trusty_app_allow_dma_range(struct trusty_app* app,
300 struct vmm_obj* obj,
301 size_t offset,
302 size_t size,
303 vaddr_t vaddr,
304 uint32_t flags);
305
306 /**
307 * trusty_app_destroy_dma_range() - Remove dma range from allowlist and release
308 * the underlying memory.
309 * @vaddr: virtual address associated with the dma range
310 *
311 * Return: NO_ERROR if the ranges were removed and ERR_INVALID_ARGS otherwise
312 */
313 status_t trusty_app_destroy_dma_range(vaddr_t vaddr, size_t size);
314
315 /**
316 * trusty_app_dma_is_allowed() - Query if the specified physical address
317 * was returned by prepare_dma and not released by finalize_dma.
318 * @app: app whose dma mappings is being queried
319 * @paddr: physical address to check
320 *
321 * Return: true if @paddr is valid and false otherwise.
322 */
323 bool trusty_app_dma_is_allowed(const struct trusty_app* app, paddr_t paddr);
324
325 /**
326 * trusty_uuid_dma_is_allowed() - Query if the specified physical address
327 * was returned by prepare_dma and not released by finalize_dma.
328 * @uuid: uuid of app whose dma mappings is being queried
329 * @paddr: physical address to check
330 *
331 * Return: true if @paddr is valid and false otherwise.
332 */
333 bool trusty_uuid_dma_is_allowed(const struct uuid* uuid, paddr_t paddr);
334
335 #endif
336