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