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 enum app_state {
39 APP_NOT_RUNNING = 0,
40 APP_STARTING,
41 APP_RUNNING,
42 APP_TERMINATING,
43 APP_RESTARTING,
44 APP_FAILED_TO_START,
45 };
46
47 /**
48 * enum app_flags - Flags for Trusty applications
49 * @APP_FLAGS_LOADABLE: This is a loadable application.
50 * @APP_FLAGS_CREATION_MASK: Flags allowed during app creation.
51 */
52 enum app_flags {
53 APP_FLAGS_LOADABLE = (1 << 0),
54
55 APP_FLAGS_CREATION_MASK = APP_FLAGS_LOADABLE,
56 };
57
58 struct manifest_port_entry {
59 uint32_t flags;
60 uint32_t path_len;
61 /* Points to a string within an application's manifest blob */
62 const char* path;
63 struct list_node node;
64 };
65
66 struct manifest_mmio_entry {
67 struct list_node node;
68 struct phys_mem_obj phys_mem_obj;
69 struct obj_ref phys_mem_obj_self_ref;
70 uint32_t id;
71 };
72
73 struct trusty_app_props {
74 uuid_t uuid;
75 const char* app_name;
76 uint32_t mgmt_flags;
77 uint32_t min_stack_size;
78 uint32_t min_heap_size;
79 uint32_t min_shadow_stack_size;
80 uint32_t map_io_mem_cnt;
81 struct list_node port_entry_list;
82 struct list_node mmio_entry_list;
83 /* record paddrs mapped by prepare_dma until released by finish_dma */
84 struct list_node dma_entry_list;
85 int pinned_cpu;
86 int priority;
87 bool feature_bti;
88 };
89
90 struct trusty_app_img {
91 uintptr_t manifest_start;
92 uintptr_t manifest_end;
93 uintptr_t img_start;
94 uintptr_t img_end;
95 };
96
97 /**
98 * struct trusty_app_mmio_allowed_range - Allowed MMIO range for loadable apps.
99 * @node: Internal list node, should be initialized to
100 * %LIST_INITIAL_CLEARED_VALUE.
101 * @uuid: The UUID of this application.
102 * @start: Start address of this range.
103 * @size: Size of this range.
104 */
105 struct trusty_app_mmio_allowed_range {
106 struct list_node node;
107 uuid_t uuid;
108 paddr_t start;
109 size_t size;
110 };
111
112 #define TRUSTY_APP_MMIO_ALLOWED_RANGE(_name, _uuid, _start, _size) \
113 static struct trusty_app_mmio_allowed_range _name = { \
114 .node = LIST_INITIAL_CLEARED_VALUE, \
115 .uuid = _uuid, \
116 .start = (_start), \
117 .size = (_size), \
118 };
119
120 /**
121 * trusty_app_allow_mmio_range() - Add a new allowed MMIO range
122 * @range: Pointer to the range to add.
123 *
124 * Adds a memory mapping to the internal list of allowed memory ranges.
125 * The underlying structure will be added to a permanent linked list,
126 * so it must not be a temporary value, e.g., on the stack.
127 * The best option is to pass in a structure created with the
128 * %TRUSTY_APP_MMIO_ALLOWED_RANGE macro.
129 *
130 * This function should be called before any loadable app is started,
131 * e.g., at init level LK_INIT_LEVEL_APPS - 1.
132 */
133 void trusty_app_allow_mmio_range(struct trusty_app_mmio_allowed_range* range);
134
135 struct trusty_app;
136
137 struct trusty_thread {
138 vaddr_t stack_start;
139 size_t stack_size;
140 #if USER_SCS_SUPPORTED
141 vaddr_t shadow_stack_base;
142 size_t shadow_stack_size;
143 #endif
144 vaddr_t entry;
145 thread_t* thread;
146 struct trusty_app* app;
147 };
148
149 struct trusty_app {
150 /* corresponds to the order in which the apps were started */
151 u_int app_id;
152 enum app_state state;
153 uint32_t flags;
154 lk_time_ns_t min_start_time;
155 vmm_aspace_t* aspace;
156 bool used_brk;
157 vaddr_t start_brk;
158 vaddr_t cur_brk;
159 vaddr_t end_brk;
160 vaddr_t load_bias;
161 struct trusty_app_props props;
162 struct trusty_app_img app_img;
163 struct trusty_thread* thread;
164 /* app local storage */
165 void** als;
166 struct list_node node;
167 };
168
169 void trusty_app_init(void);
170
171 /**
172 * trusty_app_create_and_start() - Create and start a new Trusty application
173 * @app_img: metadata of the application to load.
174 * @flags: Creation flags, values from &enum app_flags.
175 *
176 * Return: ERR_NO_MEMORY if out of memory, ERR_NOT_VALID if
177 * the application ELF or manifest are not valid.
178 */
179 status_t trusty_app_create_and_start(struct trusty_app_img* app_img,
180 uint32_t flags);
181
182 /**
183 * trusty_app_is_startup_port() - Query if the specified port is a startup port
184 * @port_path: path of the port to check.
185 *
186 * Return: true if @port_path has been registered as a startup port by an
187 * application, false otherwise.
188 */
189 bool trusty_app_is_startup_port(const char* port_path);
190
191 /**
192 * trusty_app_request_start_by_port() - Request that the application (if any)
193 * that has registered the given port be started.
194 * @port_path: path of the registered port.
195 * @uuid: uuid of the application triggering the request.
196 *
197 * If the application is already running then this function has no effect.
198 * Otherwise the application will be started.
199 *
200 * Return: ERR_NOT_FOUND if no application has registered @port_path or if the
201 * port is not accessible to @uuid, ERR_ALREADY_STARTED
202 * if the application is already running, ERR_CANCELLED if the application
203 * failed to start, or NO_ERROR otherwise.
204 */
205 status_t trusty_app_request_start_by_port(const char* port_path,
206 const uuid_t* uuid);
207
208 void trusty_app_exit(int status) __NO_RETURN;
209 void trusty_app_crash(uint32_t) __NO_RETURN;
210 status_t trusty_app_setup_mmio(struct trusty_app* trusty_app,
211 uint32_t mmio_id,
212 user_addr_t* uaddr_p,
213 uint32_t size);
214 void trusty_app_forall(void (*fn)(struct trusty_app* ta, void* data),
215 void* data);
216 void trusty_thread_exit(int status);
217
218 struct trusty_app_notifier {
219 struct list_node node;
220 status_t (*startup)(struct trusty_app* app);
221 status_t (*shutdown)(struct trusty_app* app);
222 status_t (*crash)(struct trusty_app* app, uint32_t reason, bool is_crash);
223 };
224
225 /*
226 * All app notifiers registration has to be complete before
227 * libtrusty is initialized which is happening at LK_INIT_LEVEL_APPS-1
228 * init level.
229 */
230 status_t trusty_register_app_notifier(struct trusty_app_notifier* n);
231
232 /*
233 * All als slots must be allocated before libtrusty is initialized
234 * which is happening at LK_INIT_LEVEL_APPS-1 init level.
235 */
236 int trusty_als_alloc_slot(void);
237
238 extern uint als_slot_cnt;
239
trusty_als_get(struct trusty_app * app,int slot_id)240 static inline void* trusty_als_get(struct trusty_app* app, int slot_id) {
241 uint slot = slot_id - 1;
242 ASSERT(slot < als_slot_cnt);
243 return app->als[slot];
244 }
245
trusty_als_set(struct trusty_app * app,int slot_id,void * ptr)246 static inline void trusty_als_set(struct trusty_app* app,
247 int slot_id,
248 void* ptr) {
249 uint slot = slot_id - 1;
250 ASSERT(slot < als_slot_cnt);
251 app->als[slot] = ptr;
252 }
253
trusty_thread_get(thread_t * t)254 static inline struct trusty_thread* trusty_thread_get(thread_t* t) {
255 return (struct trusty_thread*)thread_tls_get(t, TLS_ENTRY_TRUSTY);
256 }
257
current_trusty_thread(void)258 static inline struct trusty_thread* current_trusty_thread(void) {
259 return (struct trusty_thread*)tls_get(TLS_ENTRY_TRUSTY);
260 }
261
current_trusty_app(void)262 static inline struct trusty_app* current_trusty_app(void) {
263 struct trusty_thread* trusty_thread = current_trusty_thread();
264 if (!trusty_thread) {
265 return NULL;
266 }
267 return trusty_thread->app;
268 }
269
270 /**
271 * trusty_app_allow_dma_range() - Mark dma range as allowed.
272 * @app: app which should be allowed to use dma range
273 * @obj: backing object for the dma range being allowed
274 * @offset: offset into the backing object
275 * @size: size of the dma range in bytes
276 * @vaddr: virtual memory address. Used to tear down all mappings from a single
277 * call to prepare_dma
278 * @flags: flags used to map dma range
279 *
280 * Return: ERR_INVALID_ARGS if range has already been mapped, ERR_NO_MEMORY if
281 * allocation of the bookkeeping structure failed, and NO_ERROR
282 * otherwise.
283 */
284 status_t trusty_app_allow_dma_range(struct trusty_app* app,
285 struct vmm_obj* obj,
286 size_t offset,
287 size_t size,
288 vaddr_t vaddr,
289 uint32_t flags);
290
291 /**
292 * trusty_app_destroy_dma_range() - Remove dma range from allowlist and release
293 * the underlying memory.
294 * @vaddr: virtual address associated with the dma range
295 *
296 * Return: NO_ERROR if the ranges were removed and ERR_INVALID_ARGS otherwise
297 */
298 status_t trusty_app_destroy_dma_range(vaddr_t vaddr, size_t size);
299
300 /**
301 * trusty_app_dma_is_allowed() - Query if the specified physical address
302 * was returned by prepare_dma and not released by finalize_dma.
303 * @app: app whose dma mappings is being queried
304 * @paddr: physical address to check
305 *
306 * Return: true if @paddr is valid and false otherwise.
307 */
308 bool trusty_app_dma_is_allowed(const struct trusty_app* app, paddr_t paddr);
309
310 /**
311 * trusty_uuid_dma_is_allowed() - Query if the specified physical address
312 * was returned by prepare_dma and not released by finalize_dma.
313 * @uuid: uuid of app whose dma mappings is being queried
314 * @paddr: physical address to check
315 *
316 * Return: true if @paddr is valid and false otherwise.
317 */
318 bool trusty_uuid_dma_is_allowed(const struct uuid* uuid, paddr_t paddr);
319
320 #endif
321