xref: /aosp_15_r20/trusty/kernel/lib/trusty/include/lib/trusty/trusty_app.h (revision 344aa361028b423587d4ef3fa52a23d194628137)
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