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