1185b4595SMarouene Boubakri /* SPDX-License-Identifier: BSD-2-Clause */ 2185b4595SMarouene Boubakri /* 3185b4595SMarouene Boubakri * Copyright (c) 2016-2017, Linaro Limited 4185b4595SMarouene Boubakri */ 5185b4595SMarouene Boubakri 6185b4595SMarouene Boubakri #ifndef __MM_MOBJ_H 7185b4595SMarouene Boubakri #define __MM_MOBJ_H 8185b4595SMarouene Boubakri 9185b4595SMarouene Boubakri #include <compiler.h> 10185b4595SMarouene Boubakri #include <mm/core_memprot.h> 11185b4595SMarouene Boubakri #include <mm/file.h> 12185b4595SMarouene Boubakri #include <mm/fobj.h> 13185b4595SMarouene Boubakri #include <string_ext.h> 14185b4595SMarouene Boubakri #include <sys/queue.h> 15185b4595SMarouene Boubakri #include <tee_api_types.h> 16185b4595SMarouene Boubakri #include <types_ext.h> 17185b4595SMarouene Boubakri 18c1bdf4fcSJens Wiklander #include <optee_msg.h> 19c1bdf4fcSJens Wiklander 20185b4595SMarouene Boubakri struct mobj { 21185b4595SMarouene Boubakri const struct mobj_ops *ops; 22185b4595SMarouene Boubakri size_t size; 23185b4595SMarouene Boubakri size_t phys_granule; 24185b4595SMarouene Boubakri struct refcount refc; 25185b4595SMarouene Boubakri }; 26185b4595SMarouene Boubakri 27185b4595SMarouene Boubakri struct mobj_ops { 28185b4595SMarouene Boubakri void *(*get_va)(struct mobj *mobj, size_t offs); 29185b4595SMarouene Boubakri TEE_Result (*get_pa)(struct mobj *mobj, size_t offs, size_t granule, 30185b4595SMarouene Boubakri paddr_t *pa); 31185b4595SMarouene Boubakri size_t (*get_phys_offs)(struct mobj *mobj, size_t granule); 32185b4595SMarouene Boubakri TEE_Result (*get_cattr)(struct mobj *mobj, uint32_t *cattr); 33185b4595SMarouene Boubakri bool (*matches)(struct mobj *mobj, enum buf_is_attr attr); 34185b4595SMarouene Boubakri void (*free)(struct mobj *mobj); 35185b4595SMarouene Boubakri uint64_t (*get_cookie)(struct mobj *mobj); 36185b4595SMarouene Boubakri struct fobj *(*get_fobj)(struct mobj *mobj); 37185b4595SMarouene Boubakri TEE_Result (*inc_map)(struct mobj *mobj); 38185b4595SMarouene Boubakri TEE_Result (*dec_map)(struct mobj *mobj); 39185b4595SMarouene Boubakri }; 40185b4595SMarouene Boubakri 41185b4595SMarouene Boubakri extern struct mobj mobj_virt; 42185b4595SMarouene Boubakri extern struct mobj *mobj_sec_ddr; 43*ff01e245SAnton Rybakov extern struct mobj *mobj_tee_ram_rx; 44*ff01e245SAnton Rybakov extern struct mobj *mobj_tee_ram_rw; 45185b4595SMarouene Boubakri 46185b4595SMarouene Boubakri static inline void *mobj_get_va(struct mobj *mobj, size_t offset) 47185b4595SMarouene Boubakri { 48185b4595SMarouene Boubakri if (mobj && mobj->ops && mobj->ops->get_va) 49185b4595SMarouene Boubakri return mobj->ops->get_va(mobj, offset); 50185b4595SMarouene Boubakri return NULL; 51185b4595SMarouene Boubakri } 52185b4595SMarouene Boubakri 53185b4595SMarouene Boubakri static inline TEE_Result mobj_get_pa(struct mobj *mobj, size_t offs, 54185b4595SMarouene Boubakri size_t granule, paddr_t *pa) 55185b4595SMarouene Boubakri { 56185b4595SMarouene Boubakri if (mobj && mobj->ops && mobj->ops->get_pa) 57185b4595SMarouene Boubakri return mobj->ops->get_pa(mobj, offs, granule, pa); 58185b4595SMarouene Boubakri return TEE_ERROR_GENERIC; 59185b4595SMarouene Boubakri } 60185b4595SMarouene Boubakri 61185b4595SMarouene Boubakri static inline size_t mobj_get_phys_offs(struct mobj *mobj, size_t granule) 62185b4595SMarouene Boubakri { 63185b4595SMarouene Boubakri if (mobj && mobj->ops && mobj->ops->get_phys_offs) 64185b4595SMarouene Boubakri return mobj->ops->get_phys_offs(mobj, granule); 65185b4595SMarouene Boubakri return 0; 66185b4595SMarouene Boubakri } 67185b4595SMarouene Boubakri 68185b4595SMarouene Boubakri static inline TEE_Result mobj_get_cattr(struct mobj *mobj, uint32_t *cattr) 69185b4595SMarouene Boubakri { 70185b4595SMarouene Boubakri if (mobj && mobj->ops && mobj->ops->get_cattr) 71185b4595SMarouene Boubakri return mobj->ops->get_cattr(mobj, cattr); 72185b4595SMarouene Boubakri return TEE_ERROR_GENERIC; 73185b4595SMarouene Boubakri } 74185b4595SMarouene Boubakri 75185b4595SMarouene Boubakri static inline bool mobj_matches(struct mobj *mobj, enum buf_is_attr attr) 76185b4595SMarouene Boubakri { 77185b4595SMarouene Boubakri if (mobj && mobj->ops && mobj->ops->matches) 78185b4595SMarouene Boubakri return mobj->ops->matches(mobj, attr); 79185b4595SMarouene Boubakri return false; 80185b4595SMarouene Boubakri } 81185b4595SMarouene Boubakri 82185b4595SMarouene Boubakri /** 83185b4595SMarouene Boubakri * mobj_inc_map() - increase map count 84185b4595SMarouene Boubakri * @mobj: pointer to a MOBJ 85185b4595SMarouene Boubakri * 86185b4595SMarouene Boubakri * Maps the MOBJ if it isn't mapped already and increases the map count 87185b4595SMarouene Boubakri * Each call to mobj_inc_map() is supposed to be matches by a call to 88185b4595SMarouene Boubakri * mobj_dec_map(). 89185b4595SMarouene Boubakri * 90185b4595SMarouene Boubakri * Returns TEE_SUCCESS on success or an error code on failure 91185b4595SMarouene Boubakri */ 92185b4595SMarouene Boubakri static inline TEE_Result mobj_inc_map(struct mobj *mobj) 93185b4595SMarouene Boubakri { 94185b4595SMarouene Boubakri if (mobj && mobj->ops) { 95185b4595SMarouene Boubakri if (mobj->ops->inc_map) 96185b4595SMarouene Boubakri return mobj->ops->inc_map(mobj); 97185b4595SMarouene Boubakri return TEE_SUCCESS; 98185b4595SMarouene Boubakri } 99185b4595SMarouene Boubakri return TEE_ERROR_GENERIC; 100185b4595SMarouene Boubakri } 101185b4595SMarouene Boubakri 102185b4595SMarouene Boubakri /** 103185b4595SMarouene Boubakri * mobj_dec_map() - decrease map count 104185b4595SMarouene Boubakri * @mobj: pointer to a MOBJ 105185b4595SMarouene Boubakri * 106185b4595SMarouene Boubakri * Decreases the map count and also unmaps the MOBJ if the map count 107185b4595SMarouene Boubakri * reaches 0. Each call to mobj_inc_map() is supposed to be matched by a 108185b4595SMarouene Boubakri * call to mobj_dec_map(). 109185b4595SMarouene Boubakri * 110185b4595SMarouene Boubakri * Returns TEE_SUCCESS on success or an error code on failure 111185b4595SMarouene Boubakri */ 112185b4595SMarouene Boubakri static inline TEE_Result mobj_dec_map(struct mobj *mobj) 113185b4595SMarouene Boubakri { 114185b4595SMarouene Boubakri if (mobj && mobj->ops) { 115185b4595SMarouene Boubakri if (mobj->ops->dec_map) 116185b4595SMarouene Boubakri return mobj->ops->dec_map(mobj); 117185b4595SMarouene Boubakri return TEE_SUCCESS; 118185b4595SMarouene Boubakri } 119185b4595SMarouene Boubakri return TEE_ERROR_GENERIC; 120185b4595SMarouene Boubakri } 121185b4595SMarouene Boubakri 122185b4595SMarouene Boubakri /** 123185b4595SMarouene Boubakri * mobj_get() - get a MOBJ 124185b4595SMarouene Boubakri * @mobj: Pointer to a MOBJ or NULL 125185b4595SMarouene Boubakri * 126185b4595SMarouene Boubakri * Increases reference counter of the @mobj 127185b4595SMarouene Boubakri * 128185b4595SMarouene Boubakri * Returns @mobj with reference counter increased or NULL if @mobj was NULL 129185b4595SMarouene Boubakri */ 130185b4595SMarouene Boubakri static inline struct mobj *mobj_get(struct mobj *mobj) 131185b4595SMarouene Boubakri { 132185b4595SMarouene Boubakri if (mobj && !refcount_inc(&mobj->refc)) 133185b4595SMarouene Boubakri panic(); 134185b4595SMarouene Boubakri 135185b4595SMarouene Boubakri return mobj; 136185b4595SMarouene Boubakri } 137185b4595SMarouene Boubakri 138185b4595SMarouene Boubakri /** 139185b4595SMarouene Boubakri * mobj_put() - put a MOBJ 140185b4595SMarouene Boubakri * @mobj: Pointer to a MOBJ or NULL 141185b4595SMarouene Boubakri * 142185b4595SMarouene Boubakri * Decreases reference counter of the @mobj and frees it if the counter 143185b4595SMarouene Boubakri * reaches 0. 144185b4595SMarouene Boubakri */ 145185b4595SMarouene Boubakri static inline void mobj_put(struct mobj *mobj) 146185b4595SMarouene Boubakri { 147185b4595SMarouene Boubakri if (mobj && refcount_dec(&mobj->refc)) 148185b4595SMarouene Boubakri mobj->ops->free(mobj); 149185b4595SMarouene Boubakri } 150185b4595SMarouene Boubakri 151185b4595SMarouene Boubakri /** 152185b4595SMarouene Boubakri * mobj_put_wipe() - wipe and put a MOBJ 153185b4595SMarouene Boubakri * @mobj: Pointer to a MOBJ or NULL 154185b4595SMarouene Boubakri * 155185b4595SMarouene Boubakri * Clears the memory represented by the mobj and then puts it. 156185b4595SMarouene Boubakri */ 157185b4595SMarouene Boubakri static inline void mobj_put_wipe(struct mobj *mobj) 158185b4595SMarouene Boubakri { 159185b4595SMarouene Boubakri void *buf = mobj_get_va(mobj, 0); 160185b4595SMarouene Boubakri 161185b4595SMarouene Boubakri if (buf) 162185b4595SMarouene Boubakri memzero_explicit(buf, mobj->size); 163185b4595SMarouene Boubakri mobj_put(mobj); 164185b4595SMarouene Boubakri } 165185b4595SMarouene Boubakri 166185b4595SMarouene Boubakri static inline uint64_t mobj_get_cookie(struct mobj *mobj) 167185b4595SMarouene Boubakri { 168185b4595SMarouene Boubakri if (mobj && mobj->ops && mobj->ops->get_cookie) 169185b4595SMarouene Boubakri return mobj->ops->get_cookie(mobj); 170185b4595SMarouene Boubakri 171c1bdf4fcSJens Wiklander #if defined(CFG_CORE_SEL1_SPMC) || defined(CFG_CORE_SEL2_SPMC) 172c1bdf4fcSJens Wiklander return OPTEE_MSG_FMEM_INVALID_GLOBAL_ID; 173c1bdf4fcSJens Wiklander #else 174185b4595SMarouene Boubakri return 0; 175c1bdf4fcSJens Wiklander #endif 176185b4595SMarouene Boubakri } 177185b4595SMarouene Boubakri 178185b4595SMarouene Boubakri static inline struct fobj *mobj_get_fobj(struct mobj *mobj) 179185b4595SMarouene Boubakri { 180185b4595SMarouene Boubakri if (mobj && mobj->ops && mobj->ops->get_fobj) 181185b4595SMarouene Boubakri return mobj->ops->get_fobj(mobj); 182185b4595SMarouene Boubakri 183185b4595SMarouene Boubakri return NULL; 184185b4595SMarouene Boubakri } 185185b4595SMarouene Boubakri 186185b4595SMarouene Boubakri static inline bool mobj_is_nonsec(struct mobj *mobj) 187185b4595SMarouene Boubakri { 188185b4595SMarouene Boubakri return mobj_matches(mobj, CORE_MEM_NON_SEC); 189185b4595SMarouene Boubakri } 190185b4595SMarouene Boubakri 191185b4595SMarouene Boubakri static inline bool mobj_is_secure(struct mobj *mobj) 192185b4595SMarouene Boubakri { 193185b4595SMarouene Boubakri return mobj_matches(mobj, CORE_MEM_SEC); 194185b4595SMarouene Boubakri } 195185b4595SMarouene Boubakri 196185b4595SMarouene Boubakri static inline bool mobj_is_sdp_mem(struct mobj *mobj) 197185b4595SMarouene Boubakri { 198185b4595SMarouene Boubakri return mobj_matches(mobj, CORE_MEM_SDP_MEM); 199185b4595SMarouene Boubakri } 200185b4595SMarouene Boubakri 201185b4595SMarouene Boubakri static inline size_t mobj_get_phys_granule(struct mobj *mobj) 202185b4595SMarouene Boubakri { 203185b4595SMarouene Boubakri if (mobj->phys_granule) 204185b4595SMarouene Boubakri return mobj->phys_granule; 205185b4595SMarouene Boubakri return mobj->size; 206185b4595SMarouene Boubakri } 207185b4595SMarouene Boubakri 208185b4595SMarouene Boubakri struct mobj *mobj_mm_alloc(struct mobj *mobj_parent, size_t size, 209185b4595SMarouene Boubakri tee_mm_pool_t *pool); 210185b4595SMarouene Boubakri 211185b4595SMarouene Boubakri struct mobj *mobj_phys_alloc(paddr_t pa, size_t size, uint32_t cattr, 212185b4595SMarouene Boubakri enum buf_is_attr battr); 213185b4595SMarouene Boubakri 214185b4595SMarouene Boubakri #if defined(CFG_CORE_FFA) 215185b4595SMarouene Boubakri struct mobj *mobj_ffa_get_by_cookie(uint64_t cookie, 216185b4595SMarouene Boubakri unsigned int internal_offs); 217185b4595SMarouene Boubakri 218185b4595SMarouene Boubakri TEE_Result mobj_ffa_unregister_by_cookie(uint64_t cookie); 219185b4595SMarouene Boubakri 220185b4595SMarouene Boubakri /* Functions for SPMC */ 221185b4595SMarouene Boubakri #ifdef CFG_CORE_SEL1_SPMC 222185b4595SMarouene Boubakri struct mobj_ffa *mobj_ffa_sel1_spmc_new(unsigned int num_pages); 223185b4595SMarouene Boubakri void mobj_ffa_sel1_spmc_delete(struct mobj_ffa *mobj); 224185b4595SMarouene Boubakri TEE_Result mobj_ffa_sel1_spmc_reclaim(uint64_t cookie); 225185b4595SMarouene Boubakri #endif 226fb19e98eSJens Wiklander #ifdef CFG_CORE_SEL2_SPMC 227fb19e98eSJens Wiklander struct mobj_ffa *mobj_ffa_sel2_spmc_new(uint64_t cookie, 228fb19e98eSJens Wiklander unsigned int num_pages); 229fb19e98eSJens Wiklander void mobj_ffa_sel2_spmc_delete(struct mobj_ffa *mobj); 230fb19e98eSJens Wiklander #endif 231fb19e98eSJens Wiklander 232185b4595SMarouene Boubakri uint64_t mobj_ffa_get_cookie(struct mobj_ffa *mobj); 233185b4595SMarouene Boubakri TEE_Result mobj_ffa_add_pages_at(struct mobj_ffa *mobj, unsigned int *idx, 234185b4595SMarouene Boubakri paddr_t pa, unsigned int num_pages); 235185b4595SMarouene Boubakri uint64_t mobj_ffa_push_to_inactive(struct mobj_ffa *mobj); 236185b4595SMarouene Boubakri 237185b4595SMarouene Boubakri #elif defined(CFG_CORE_DYN_SHM) 238185b4595SMarouene Boubakri /* reg_shm represents TEE shared memory */ 239185b4595SMarouene Boubakri struct mobj *mobj_reg_shm_alloc(paddr_t *pages, size_t num_pages, 240185b4595SMarouene Boubakri paddr_t page_offset, uint64_t cookie); 241185b4595SMarouene Boubakri 242185b4595SMarouene Boubakri /** 243185b4595SMarouene Boubakri * mobj_reg_shm_get_by_cookie() - get a MOBJ based on cookie 244185b4595SMarouene Boubakri * @cookie: Cookie used by normal world when suppling the shared memory 245185b4595SMarouene Boubakri * 246185b4595SMarouene Boubakri * Searches for a registered shared memory MOBJ and if one with a matching 247185b4595SMarouene Boubakri * @cookie is found its reference counter is increased before returning 248185b4595SMarouene Boubakri * the MOBJ. 249185b4595SMarouene Boubakri * 250185b4595SMarouene Boubakri * Returns a valid pointer on success or NULL on failure. 251185b4595SMarouene Boubakri */ 252185b4595SMarouene Boubakri struct mobj *mobj_reg_shm_get_by_cookie(uint64_t cookie); 253185b4595SMarouene Boubakri 254185b4595SMarouene Boubakri TEE_Result mobj_reg_shm_release_by_cookie(uint64_t cookie); 255185b4595SMarouene Boubakri 256185b4595SMarouene Boubakri /** 257185b4595SMarouene Boubakri * mobj_reg_shm_unguard() - unguards a reg_shm 258185b4595SMarouene Boubakri * @mobj: pointer to a registered shared memory mobj 259185b4595SMarouene Boubakri * 260185b4595SMarouene Boubakri * A registered shared memory mobj is normally guarded against being 261185b4595SMarouene Boubakri * released with mobj_reg_shm_try_release_by_cookie(). After this function 262185b4595SMarouene Boubakri * has returned the mobj can be released by a call to 263185b4595SMarouene Boubakri * mobj_reg_shm_try_release_by_cookie() if the reference counter allows it. 264185b4595SMarouene Boubakri */ 265185b4595SMarouene Boubakri void mobj_reg_shm_unguard(struct mobj *mobj); 266185b4595SMarouene Boubakri 267185b4595SMarouene Boubakri /* 268185b4595SMarouene Boubakri * mapped_shm represents registered shared buffer 269185b4595SMarouene Boubakri * which is mapped into OPTEE va space 270185b4595SMarouene Boubakri */ 271185b4595SMarouene Boubakri struct mobj *mobj_mapped_shm_alloc(paddr_t *pages, size_t num_pages, 272185b4595SMarouene Boubakri paddr_t page_offset, uint64_t cookie); 273185b4595SMarouene Boubakri #endif /*CFG_CORE_DYN_SHM*/ 274185b4595SMarouene Boubakri 275185b4595SMarouene Boubakri #if !defined(CFG_CORE_DYN_SHM) 276185b4595SMarouene Boubakri static inline struct mobj *mobj_mapped_shm_alloc(paddr_t *pages __unused, 277185b4595SMarouene Boubakri size_t num_pages __unused, 278185b4595SMarouene Boubakri paddr_t page_offset __unused, 279185b4595SMarouene Boubakri uint64_t cookie __unused) 280185b4595SMarouene Boubakri { 281185b4595SMarouene Boubakri return NULL; 282185b4595SMarouene Boubakri } 283185b4595SMarouene Boubakri #endif 284185b4595SMarouene Boubakri 285185b4595SMarouene Boubakri struct mobj *mobj_shm_alloc(paddr_t pa, size_t size, uint64_t cookie); 286185b4595SMarouene Boubakri 287185b4595SMarouene Boubakri #ifdef CFG_PAGED_USER_TA 288185b4595SMarouene Boubakri bool mobj_is_paged(struct mobj *mobj); 289185b4595SMarouene Boubakri #else 290185b4595SMarouene Boubakri static inline bool mobj_is_paged(struct mobj *mobj __unused) 291185b4595SMarouene Boubakri { 292185b4595SMarouene Boubakri return false; 293185b4595SMarouene Boubakri } 294185b4595SMarouene Boubakri #endif 295185b4595SMarouene Boubakri 296185b4595SMarouene Boubakri struct mobj *mobj_seccpy_shm_alloc(size_t size); 297185b4595SMarouene Boubakri 298185b4595SMarouene Boubakri struct mobj *mobj_with_fobj_alloc(struct fobj *fobj, struct file *file); 299185b4595SMarouene Boubakri 300185b4595SMarouene Boubakri #endif /*__MM_MOBJ_H*/ 301