Loading drivers/tee/tee_core.c +31 −9 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ static int tee_open(struct inode *inode, struct file *filp) goto err; } kref_init(&ctx->refcount); ctx->teedev = teedev; INIT_LIST_HEAD(&ctx->list_shm); filp->private_data = ctx; Loading @@ -68,19 +69,40 @@ static int tee_open(struct inode *inode, struct file *filp) return rc; } static int tee_release(struct inode *inode, struct file *filp) void teedev_ctx_get(struct tee_context *ctx) { struct tee_context *ctx = filp->private_data; struct tee_device *teedev = ctx->teedev; struct tee_shm *shm; if (ctx->releasing) return; kref_get(&ctx->refcount); } static void teedev_ctx_release(struct kref *ref) { struct tee_context *ctx = container_of(ref, struct tee_context, refcount); ctx->releasing = true; ctx->teedev->desc->ops->release(ctx); mutex_lock(&ctx->teedev->mutex); list_for_each_entry(shm, &ctx->list_shm, link) shm->ctx = NULL; mutex_unlock(&ctx->teedev->mutex); kfree(ctx); tee_device_put(teedev); } void teedev_ctx_put(struct tee_context *ctx) { if (ctx->releasing) return; kref_put(&ctx->refcount, teedev_ctx_release); } static void teedev_close_context(struct tee_context *ctx) { tee_device_put(ctx->teedev); teedev_ctx_put(ctx); } static int tee_release(struct inode *inode, struct file *filp) { teedev_close_context(filp->private_data); return 0; } Loading drivers/tee/tee_private.h +3 −0 Original line number Diff line number Diff line Loading @@ -73,4 +73,7 @@ int tee_shm_get_fd(struct tee_shm *shm); bool tee_device_get(struct tee_device *teedev); void tee_device_put(struct tee_device *teedev); void teedev_ctx_get(struct tee_context *ctx); void teedev_ctx_put(struct tee_context *ctx); #endif /*TEE_PRIVATE_H*/ drivers/tee/tee_shm.c +7 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,9 @@ static void tee_shm_release(struct tee_shm *shm) kfree(shm->pages); } if (shm->ctx) teedev_ctx_put(shm->ctx); kfree(shm); tee_device_put(teedev); Loading Loading @@ -187,6 +190,7 @@ struct tee_shm *__tee_shm_alloc(struct tee_context *ctx, } if (ctx) { teedev_ctx_get(ctx); mutex_lock(&teedev->mutex); list_add_tail(&shm->link, &ctx->list_shm); mutex_unlock(&teedev->mutex); Loading Loading @@ -253,6 +257,8 @@ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr, return ERR_PTR(-ENOTSUPP); } teedev_ctx_get(ctx); shm = kzalloc(sizeof(*shm), GFP_KERNEL); if (!shm) { ret = ERR_PTR(-ENOMEM); Loading Loading @@ -334,6 +340,7 @@ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr, kfree(shm->pages); } kfree(shm); teedev_ctx_put(ctx); tee_device_put(teedev); return ret; } Loading include/linux/tee_drv.h +7 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/types.h> #include <linux/idr.h> #include <linux/kref.h> #include <linux/list.h> #include <linux/tee.h> Loading @@ -42,11 +43,17 @@ struct tee_shm_pool; * @teedev: pointer to this drivers struct tee_device * @list_shm: List of shared memory object owned by this context * @data: driver specific context data, managed by the driver * @refcount: reference counter for this structure * @releasing: flag that indicates if context is being released right now. * It is needed to break circular dependency on context during * shared memory release. */ struct tee_context { struct tee_device *teedev; struct list_head list_shm; void *data; struct kref refcount; bool releasing; }; struct tee_param_memref { Loading Loading
drivers/tee/tee_core.c +31 −9 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ static int tee_open(struct inode *inode, struct file *filp) goto err; } kref_init(&ctx->refcount); ctx->teedev = teedev; INIT_LIST_HEAD(&ctx->list_shm); filp->private_data = ctx; Loading @@ -68,19 +69,40 @@ static int tee_open(struct inode *inode, struct file *filp) return rc; } static int tee_release(struct inode *inode, struct file *filp) void teedev_ctx_get(struct tee_context *ctx) { struct tee_context *ctx = filp->private_data; struct tee_device *teedev = ctx->teedev; struct tee_shm *shm; if (ctx->releasing) return; kref_get(&ctx->refcount); } static void teedev_ctx_release(struct kref *ref) { struct tee_context *ctx = container_of(ref, struct tee_context, refcount); ctx->releasing = true; ctx->teedev->desc->ops->release(ctx); mutex_lock(&ctx->teedev->mutex); list_for_each_entry(shm, &ctx->list_shm, link) shm->ctx = NULL; mutex_unlock(&ctx->teedev->mutex); kfree(ctx); tee_device_put(teedev); } void teedev_ctx_put(struct tee_context *ctx) { if (ctx->releasing) return; kref_put(&ctx->refcount, teedev_ctx_release); } static void teedev_close_context(struct tee_context *ctx) { tee_device_put(ctx->teedev); teedev_ctx_put(ctx); } static int tee_release(struct inode *inode, struct file *filp) { teedev_close_context(filp->private_data); return 0; } Loading
drivers/tee/tee_private.h +3 −0 Original line number Diff line number Diff line Loading @@ -73,4 +73,7 @@ int tee_shm_get_fd(struct tee_shm *shm); bool tee_device_get(struct tee_device *teedev); void tee_device_put(struct tee_device *teedev); void teedev_ctx_get(struct tee_context *ctx); void teedev_ctx_put(struct tee_context *ctx); #endif /*TEE_PRIVATE_H*/
drivers/tee/tee_shm.c +7 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,9 @@ static void tee_shm_release(struct tee_shm *shm) kfree(shm->pages); } if (shm->ctx) teedev_ctx_put(shm->ctx); kfree(shm); tee_device_put(teedev); Loading Loading @@ -187,6 +190,7 @@ struct tee_shm *__tee_shm_alloc(struct tee_context *ctx, } if (ctx) { teedev_ctx_get(ctx); mutex_lock(&teedev->mutex); list_add_tail(&shm->link, &ctx->list_shm); mutex_unlock(&teedev->mutex); Loading Loading @@ -253,6 +257,8 @@ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr, return ERR_PTR(-ENOTSUPP); } teedev_ctx_get(ctx); shm = kzalloc(sizeof(*shm), GFP_KERNEL); if (!shm) { ret = ERR_PTR(-ENOMEM); Loading Loading @@ -334,6 +340,7 @@ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr, kfree(shm->pages); } kfree(shm); teedev_ctx_put(ctx); tee_device_put(teedev); return ret; } Loading
include/linux/tee_drv.h +7 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/types.h> #include <linux/idr.h> #include <linux/kref.h> #include <linux/list.h> #include <linux/tee.h> Loading @@ -42,11 +43,17 @@ struct tee_shm_pool; * @teedev: pointer to this drivers struct tee_device * @list_shm: List of shared memory object owned by this context * @data: driver specific context data, managed by the driver * @refcount: reference counter for this structure * @releasing: flag that indicates if context is being released right now. * It is needed to break circular dependency on context during * shared memory release. */ struct tee_context { struct tee_device *teedev; struct list_head list_shm; void *data; struct kref refcount; bool releasing; }; struct tee_param_memref { Loading