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