xref: /optee_os/core/include/mm/fobj.h (revision 5a913ee74d3c71af2a2860ce8a4e7aeab2916f9b)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (c) 2019, Linaro Limited
4  */
5 
6 #ifndef __MM_FOBJ_H
7 #define __MM_FOBJ_H
8 
9 #include <kernel/panic.h>
10 #include <kernel/refcount.h>
11 #include <mm/tee_pager.h>
12 #include <sys/queue.h>
13 #include <tee_api_types.h>
14 #include <types_ext.h>
15 
16 /*
17  * struct fobj - file object storage abstraction
18  * @ops:	Operations pointer
19  * @num_pages:	Number of pages covered
20  * @refc:	Reference counter
21  */
22 struct fobj {
23 	const struct fobj_ops *ops;
24 	unsigned int num_pages;
25 	struct refcount refc;
26 #ifdef CFG_WITH_PAGER
27 	struct tee_pager_area_head areas;
28 #endif
29 };
30 
31 /*
32  * struct fobj_ops - operations struct for struct fobj
33  * @free:	Frees the @fobj
34  * @load_page:	Loads page with index @page_idx at address @va
35  * @save_page:	Saves page with index @page_idx from address @va
36  * @get_pa:	Returns physical address of page at @page_idx if not paged
37  */
38 struct fobj_ops {
39 	void (*free)(struct fobj *fobj);
40 #ifdef CFG_WITH_PAGER
41 	TEE_Result (*load_page)(struct fobj *fobj, unsigned int page_idx,
42 				void *va);
43 	TEE_Result (*save_page)(struct fobj *fobj, unsigned int page_idx,
44 				const void *va);
45 #endif
46 	paddr_t (*get_pa)(struct fobj *fobj, unsigned int page_idx);
47 };
48 
49 #ifdef CFG_WITH_PAGER
50 /*
51  * fobj_locked_paged_alloc() - Allocate storage which is locked in memory
52  * @num_pages:	Number of pages covered
53  *
54  * This object only supports loading pages zero initialized. Saving a page
55  * will result in an error.
56  *
57  * Returns a valid pointer on success or NULL on failure.
58  */
59 struct fobj *fobj_locked_paged_alloc(unsigned int num_pages);
60 
61 /*
62  * fobj_rw_paged_alloc() - Allocate read/write storage
63  * @num_pages:	Number of pages covered
64  *
65  * This object supports both load and saving of pages. Pages are zero
66  * initialized the first time they are loaded.
67  *
68  * Returns a valid pointer on success or NULL on failure.
69  */
70 struct fobj *fobj_rw_paged_alloc(unsigned int num_pages);
71 
72 /*
73  * fobj_ro_paged_alloc() - Allocate initialized read-only storage
74  * @num_pages:	Number of pages covered
75  * @hashes:	Hashes to verify the pages
76  * @store:	Clear text data for all pages
77  *
78  * This object only support loading pages with an already provided content
79  * in @store. When a page is loaded it will be verified against an hash in
80  * @hash. Saving a page will result in an error.
81  *
82  * Returns a valid pointer on success or NULL on failure.
83  */
84 struct fobj *fobj_ro_paged_alloc(unsigned int num_pages, void *hashes,
85 				 void *store);
86 
87 /*
88  * fobj_load_page() - Load a page into memory
89  * @fobj:	Fobj pointer
90  * @page_index:	Index of page in @fobj
91  * @va:		Address where content should be stored and verified
92  *
93  * Returns TEE_SUCCESS on success or TEE_ERROR_* on failure.
94  */
95 static inline TEE_Result fobj_load_page(struct fobj *fobj,
96 					unsigned int page_idx, void *va)
97 {
98 	if (fobj)
99 		return fobj->ops->load_page(fobj, page_idx, va);
100 
101 	return TEE_ERROR_GENERIC;
102 }
103 
104 /*
105  * fobj_save_page() - Save a page into storage
106  * @fobj:	Fobj pointer
107  * @page_index:	Index of page in @fobj
108  * @va:		Address of the page to store.
109  *
110  * Returns TEE_SUCCESS on success or TEE_ERROR_* on failure.
111  */
112 static inline TEE_Result fobj_save_page(struct fobj *fobj,
113 					unsigned int page_idx, const void *va)
114 {
115 	if (fobj)
116 		return fobj->ops->save_page(fobj, page_idx, va);
117 
118 	return TEE_ERROR_GENERIC;
119 }
120 #endif
121 
122 /*
123  * fobj_ta_mem_alloc() - Allocates TA memory
124  * @num_pages:	Number of pages
125  *
126  * If paging of user TAs read/write paged fobj is allocated otherwise a
127  * fobj which uses unpaged secure memory directly.
128  *
129  * Returns a valid pointer on success or NULL on failure.
130  */
131 #ifdef CFG_PAGED_USER_TA
132 #define fobj_ta_mem_alloc(num_pages)	fobj_rw_paged_alloc(num_pages)
133 #else
134 /*
135  * fobj_sec_mem_alloc() - Allocates storage directly in secure memory
136  * @num_pages:	Number of pages
137  *
138  * Returns a valid pointer on success or NULL on failure.
139  */
140 struct fobj *fobj_sec_mem_alloc(unsigned int num_pages);
141 
142 #define fobj_ta_mem_alloc(num_pages)	fobj_sec_mem_alloc(num_pages)
143 #endif
144 
145 /*
146  * fobj_get() - Increase fobj reference count
147  * @fobj:	Fobj pointer
148  *
149  * Returns @fobj, if @fobj isn't NULL its reference counter is first
150  * increased.
151  */
152 static inline struct fobj *fobj_get(struct fobj *fobj)
153 {
154 	if (fobj && !refcount_inc(&fobj->refc))
155 		panic();
156 
157 	return fobj;
158 }
159 
160 /*
161  * fobj_put() - Decrease reference counter of fobj
162  * @fobj:	Fobj pointer
163  *
164  * If reference counter reaches 0, matching the numbers of fobj_alloc_*() +
165  * fobj_get(), the fobj is freed.
166  */
167 static inline void fobj_put(struct fobj *fobj)
168 {
169 	if (fobj && refcount_dec(&fobj->refc))
170 		fobj->ops->free(fobj);
171 }
172 
173 #ifdef CFG_WITH_PAGER
174 /*
175  * fobj_generate_authenc_key() - Generate authentication key
176  *
177  * Generates the authentication key used in all fobjs allocated with
178  * fobj_rw_paged_alloc().
179  */
180 void fobj_generate_authenc_key(void);
181 #else
182 static inline void fobj_generate_authenc_key(void)
183 {
184 }
185 #endif
186 
187 #endif /*__MM_FOBJ_H*/
188