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