xref: /optee_os/core/include/mm/fobj.h (revision ee5462896afc0dea013d2c3e9f99ce39626b148e)
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  */
32 struct fobj_ops {
33 	void (*free)(struct fobj *fobj);
34 #ifdef CFG_WITH_PAGER
35 	TEE_Result (*load_page)(struct fobj *fobj, unsigned int page_idx,
36 				void *va);
37 	TEE_Result (*save_page)(struct fobj *fobj, unsigned int page_idx,
38 				const void *va);
39 #endif
40 };
41 
42 #ifdef CFG_WITH_PAGER
43 /*
44  * fobj_locked_paged_alloc() - Allocate storage which is locked in memory
45  * @num_pages:	Number of pages covered
46  *
47  * This object only supports loading pages zero initialized. Saving a page
48  * will result in an error.
49  *
50  * Returns a valid pointer on success or NULL on failure.
51  */
52 struct fobj *fobj_locked_paged_alloc(unsigned int num_pages);
53 
54 /*
55  * fobj_rw_paged_alloc() - Allocate read/write storage
56  * @num_pages:	Number of pages covered
57  *
58  * This object supports both load and saving of pages. Pages are zero
59  * initialized the first time they are loaded.
60  *
61  * Returns a valid pointer on success or NULL on failure.
62  */
63 struct fobj *fobj_rw_paged_alloc(unsigned int num_pages);
64 
65 /*
66  * fobj_ro_paged_alloc() - Allocate initialized read-only storage
67  * @num_pages:	Number of pages covered
68  * @hashes:	Hashes to verify the pages
69  * @store:	Clear text data for all pages
70  *
71  * This object only support loading pages with an already provided content
72  * in @store. When a page is loaded it will be verified against an hash in
73  * @hash. Saving a page will result in an error.
74  *
75  * Returns a valid pointer on success or NULL on failure.
76  */
77 struct fobj *fobj_ro_paged_alloc(unsigned int num_pages, void *hashes,
78 				 void *store);
79 
80 /*
81  * fobj_load_page() - Load a page into memory
82  * @fobj:	Fobj pointer
83  * @page_index:	Index of page in @fobj
84  * @va:		Address where content should be stored and verified
85  *
86  * Returns TEE_SUCCESS on success or TEE_ERROR_* on failure.
87  */
88 static inline TEE_Result fobj_load_page(struct fobj *fobj,
89 					unsigned int page_idx, void *va)
90 {
91 	if (fobj)
92 		return fobj->ops->load_page(fobj, page_idx, va);
93 
94 	return TEE_ERROR_GENERIC;
95 }
96 
97 /*
98  * fobj_save_page() - Save a page into storage
99  * @fobj:	Fobj pointer
100  * @page_index:	Index of page in @fobj
101  * @va:		Address of the page to store.
102  *
103  * Returns TEE_SUCCESS on success or TEE_ERROR_* on failure.
104  */
105 static inline TEE_Result fobj_save_page(struct fobj *fobj,
106 					unsigned int page_idx, const void *va)
107 {
108 	if (fobj)
109 		return fobj->ops->save_page(fobj, page_idx, va);
110 
111 	return TEE_ERROR_GENERIC;
112 }
113 #endif
114 
115 /*
116  * fobj_get() - Increase fobj reference count
117  * @fobj:	Fobj pointer
118  *
119  * Returns @fobj, if @fobj isn't NULL its reference counter is first
120  * increased.
121  */
122 static inline struct fobj *fobj_get(struct fobj *fobj)
123 {
124 	if (fobj && !refcount_inc(&fobj->refc))
125 		panic();
126 
127 	return fobj;
128 }
129 
130 /*
131  * fobj_put() - Decrease reference counter of fobj
132  * @fobj:	Fobj pointer
133  *
134  * If reference counter reaches 0, matching the numbers of fobj_alloc_*() +
135  * fobj_get(), the fobj is freed.
136  */
137 static inline void fobj_put(struct fobj *fobj)
138 {
139 	if (fobj && refcount_dec(&fobj->refc))
140 		fobj->ops->free(fobj);
141 }
142 
143 #ifdef CFG_WITH_PAGER
144 /*
145  * fobj_generate_authenc_key() - Generate authentication key
146  *
147  * Generates the authentication key used in all fobjs allocated with
148  * fobj_rw_paged_alloc().
149  */
150 void fobj_generate_authenc_key(void);
151 #else
152 static inline void fobj_generate_authenc_key(void)
153 {
154 }
155 #endif
156 
157 #endif /*__MM_FOBJ_H*/
158