diff options
author | Jens Wiklander <jens.wiklander@linaro.org> | 2018-09-26 15:32:45 +0200 |
---|---|---|
committer | Jérôme Forissier <jerome.forissier@linaro.org> | 2018-10-01 17:57:03 +0200 |
commit | 8b0c1367d49d4a0fe7e8293753640a28fef7a5e0 (patch) | |
tree | 6b7ae0eadeb955362735eecebcab1b349575cb54 | |
parent | 09614f8e34cbdd8764453835ae22ee0d4826f49f (diff) |
core: add mobj_reg_shm_put()
Adds mobj_reg_shm_put() for reference counting without cookie.
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
-rw-r--r-- | core/arch/arm/include/mm/mobj.h | 19 | ||||
-rw-r--r-- | core/arch/arm/mm/mobj.c | 27 |
2 files changed, 46 insertions, 0 deletions
diff --git a/core/arch/arm/include/mm/mobj.h b/core/arch/arm/include/mm/mobj.h index fb5f257f..f72bb5f2 100644 --- a/core/arch/arm/include/mm/mobj.h +++ b/core/arch/arm/include/mm/mobj.h @@ -119,7 +119,26 @@ struct mobj *mobj_reg_shm_alloc(paddr_t *pages, size_t num_pages, void mobj_reg_shm_free_by_cookie(uint64_t cookie); +/** + * mobj_reg_shm_get_by_cookie() - get a MOBJ based on cookie + * @cookie: Cookie used by normal world when suppling the shared memory + * + * Searches for a registered shared memory MOBJ and if one with a matching + * @cookie is found its reference counter is increased before returning + * the MOBJ. + * + * Returns a valid pointer on success or NULL on failure. + */ struct mobj *mobj_reg_shm_get_by_cookie(uint64_t cookie); + +/** + * mobj_reg_shm_put() - put a MOBJ + * @mobj: Pointer to a registered shared memory MOBJ + * + * Decreases reference counter of the @mobj and frees it if the counter + * reaches 0. + */ +void mobj_reg_shm_put(struct mobj *mobj); void mobj_reg_shm_put_by_cookie(uint64_t cookie); TEE_Result mobj_reg_shm_release_by_cookie(uint64_t cookie); diff --git a/core/arch/arm/mm/mobj.c b/core/arch/arm/mm/mobj.c index ba4a483f..5be15dcd 100644 --- a/core/arch/arm/mm/mobj.c +++ b/core/arch/arm/mm/mobj.c @@ -531,6 +531,33 @@ struct mobj *mobj_reg_shm_get_by_cookie(uint64_t cookie) return NULL; } +void mobj_reg_shm_put(struct mobj *mobj) +{ + struct mobj_reg_shm *r = to_mobj_reg_shm(mobj); + uint32_t exceptions = cpu_spin_lock_xsave(®_shm_slist_lock); + + /* + * A put is supposed to match a get. The counter is supposed to be + * larger than 1, if it isn't we're in trouble. + */ + if (refcount_dec(&r->refcount)) + panic(); + + cpu_spin_unlock_xrestore(®_shm_slist_lock, exceptions); + + /* + * Note that we're reading this mutex protected variable without the + * mutex acquired. This isn't a problem since an eventually missed + * waiter who is waiting for this MOBJ will try again before hanging + * in condvar_wait(). + */ + if (shm_release_waiters) { + mutex_lock(&shm_mu); + condvar_broadcast(&shm_cv); + mutex_unlock(&shm_mu); + } +} + void mobj_reg_shm_put_by_cookie(uint64_t cookie) { uint32_t exceptions = cpu_spin_lock_xsave(®_shm_slist_lock); |