From 8b0c1367d49d4a0fe7e8293753640a28fef7a5e0 Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Wed, 26 Sep 2018 15:32:45 +0200 Subject: core: add mobj_reg_shm_put() Adds mobj_reg_shm_put() for reference counting without cookie. Reviewed-by: Etienne Carriere Signed-off-by: Jens Wiklander --- core/arch/arm/include/mm/mobj.h | 19 +++++++++++++++++++ core/arch/arm/mm/mobj.c | 27 +++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) 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); -- cgit v1.2.3