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_ro_reloc_paged_alloc() - Allocate initialized read-only storage with 89 * relocation 90 * @num_pages: Number of pages covered 91 * @hashes: Hashes to verify the pages 92 * @reloc_offs: Offset from the base address in the relocations in @reloc 93 * @reloc: Relocation data 94 * @reloc_len: Length of relocation data 95 * @store: Clear text data for all pages 96 * 97 * This object is like fobj_ro_paged_alloc() above, but in addition the 98 * relocation information is applied to a populated page. This makes sure 99 * the offset to which all pages are relocated doesn't leak out to storage. 100 * 101 * Returns a valid pointer on success or NULL on failure. 102 */ 103 struct fobj *fobj_ro_reloc_paged_alloc(unsigned int num_pages, void *hashes, 104 unsigned int reloc_offs, 105 const void *reloc, 106 unsigned int reloc_len, void *store); 107 108 /* 109 * fobj_load_page() - Load a page into memory 110 * @fobj: Fobj pointer 111 * @page_index: Index of page in @fobj 112 * @va: Address where content should be stored and verified 113 * 114 * Returns TEE_SUCCESS on success or TEE_ERROR_* on failure. 115 */ 116 static inline TEE_Result fobj_load_page(struct fobj *fobj, 117 unsigned int page_idx, void *va) 118 { 119 if (fobj) 120 return fobj->ops->load_page(fobj, page_idx, va); 121 122 return TEE_ERROR_GENERIC; 123 } 124 125 /* 126 * fobj_save_page() - Save a page into storage 127 * @fobj: Fobj pointer 128 * @page_index: Index of page in @fobj 129 * @va: Address of the page to store. 130 * 131 * Returns TEE_SUCCESS on success or TEE_ERROR_* on failure. 132 */ 133 static inline TEE_Result fobj_save_page(struct fobj *fobj, 134 unsigned int page_idx, const void *va) 135 { 136 if (fobj) 137 return fobj->ops->save_page(fobj, page_idx, va); 138 139 return TEE_ERROR_GENERIC; 140 } 141 #endif 142 143 /* 144 * fobj_ta_mem_alloc() - Allocates TA memory 145 * @num_pages: Number of pages 146 * 147 * If paging of user TAs read/write paged fobj is allocated otherwise a 148 * fobj which uses unpaged secure memory directly. 149 * 150 * Returns a valid pointer on success or NULL on failure. 151 */ 152 #ifdef CFG_PAGED_USER_TA 153 #define fobj_ta_mem_alloc(num_pages) fobj_rw_paged_alloc(num_pages) 154 #else 155 /* 156 * fobj_sec_mem_alloc() - Allocates storage directly in secure memory 157 * @num_pages: Number of pages 158 * 159 * Returns a valid pointer on success or NULL on failure. 160 */ 161 struct fobj *fobj_sec_mem_alloc(unsigned int num_pages); 162 163 #define fobj_ta_mem_alloc(num_pages) fobj_sec_mem_alloc(num_pages) 164 #endif 165 166 /* 167 * fobj_get() - Increase fobj reference count 168 * @fobj: Fobj pointer 169 * 170 * Returns @fobj, if @fobj isn't NULL its reference counter is first 171 * increased. 172 */ 173 static inline struct fobj *fobj_get(struct fobj *fobj) 174 { 175 if (fobj && !refcount_inc(&fobj->refc)) 176 panic(); 177 178 return fobj; 179 } 180 181 /* 182 * fobj_put() - Decrease reference counter of fobj 183 * @fobj: Fobj pointer 184 * 185 * If reference counter reaches 0, matching the numbers of fobj_alloc_*() + 186 * fobj_get(), the fobj is freed. 187 */ 188 static inline void fobj_put(struct fobj *fobj) 189 { 190 if (fobj && refcount_dec(&fobj->refc)) 191 fobj->ops->free(fobj); 192 } 193 194 #ifdef CFG_WITH_PAGER 195 /* 196 * fobj_generate_authenc_key() - Generate authentication key 197 * 198 * Generates the authentication key used in all fobjs allocated with 199 * fobj_rw_paged_alloc(). 200 */ 201 void fobj_generate_authenc_key(void); 202 #else 203 static inline void fobj_generate_authenc_key(void) 204 { 205 } 206 #endif 207 208 #endif /*__MM_FOBJ_H*/ 209