aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Wiklander <jens.wiklander@linaro.org>2018-09-26 15:32:45 +0200
committerJérôme Forissier <jerome.forissier@linaro.org>2018-10-01 17:57:03 +0200
commit8b0c1367d49d4a0fe7e8293753640a28fef7a5e0 (patch)
tree6b7ae0eadeb955362735eecebcab1b349575cb54
parent09614f8e34cbdd8764453835ae22ee0d4826f49f (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.h19
-rw-r--r--core/arch/arm/mm/mobj.c27
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(&reg_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(&reg_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(&reg_shm_slist_lock);