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