Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tee: add close_context to TEE driver operation

The tee_context can be used to manage TEE user resources, including
those allocated by the driver for the TEE on behalf of the user.
The release() callback is invoked only when all resources, such as
tee_shm, are released and there are no references to the tee_context.

When a user closes the device file, the driver should notify the
TEE to release any resources it may hold and drop the context
references. To achieve this, a close_context() callback is
introduced to initiate resource release in the TEE driver when
the device file is closed.

Relocate teedev_ctx_get, teedev_ctx_put, tee_device_get, and
tee_device_get functions to tee_core.h to make them accessible
outside the TEE subsystem.

Reviewed-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org>
Tested-by: Harshal Dev <quic_hdev@quicinc.com>
Signed-off-by: Amirreza Zarrabi <amirreza.zarrabi@oss.qualcomm.com>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>

authored by

Amirreza Zarrabi and committed by
Jens Wiklander
0cbaf65c 6dbcd5a9

+55 -8
+7
drivers/tee/tee_core.c
··· 80 80 81 81 kref_get(&ctx->refcount); 82 82 } 83 + EXPORT_SYMBOL_GPL(teedev_ctx_get); 83 84 84 85 static void teedev_ctx_release(struct kref *ref) 85 86 { ··· 98 97 99 98 kref_put(&ctx->refcount, teedev_ctx_release); 100 99 } 100 + EXPORT_SYMBOL_GPL(teedev_ctx_put); 101 101 102 102 void teedev_close_context(struct tee_context *ctx) 103 103 { 104 104 struct tee_device *teedev = ctx->teedev; 105 + 106 + if (teedev->desc->ops->close_context) 107 + teedev->desc->ops->close_context(ctx); 105 108 106 109 teedev_ctx_put(ctx); 107 110 tee_device_put(teedev); ··· 1117 1112 } 1118 1113 mutex_unlock(&teedev->mutex); 1119 1114 } 1115 + EXPORT_SYMBOL_GPL(tee_device_put); 1120 1116 1121 1117 bool tee_device_get(struct tee_device *teedev) 1122 1118 { ··· 1130 1124 mutex_unlock(&teedev->mutex); 1131 1125 return true; 1132 1126 } 1127 + EXPORT_SYMBOL_GPL(tee_device_get); 1133 1128 1134 1129 /** 1135 1130 * tee_device_unregister() - Removes a TEE device
-6
drivers/tee/tee_private.h
··· 23 23 24 24 int tee_shm_get_fd(struct tee_shm *shm); 25 25 26 - bool tee_device_get(struct tee_device *teedev); 27 - void tee_device_put(struct tee_device *teedev); 28 - 29 - void teedev_ctx_get(struct tee_context *ctx); 30 - void teedev_ctx_put(struct tee_context *ctx); 31 - 32 26 struct tee_shm *tee_shm_alloc_user_buf(struct tee_context *ctx, size_t size); 33 27 struct tee_shm *tee_shm_register_user_buf(struct tee_context *ctx, 34 28 unsigned long addr, size_t length);
+48 -2
include/linux/tee_core.h
··· 76 76 /** 77 77 * struct tee_driver_ops - driver operations vtable 78 78 * @get_version: returns version of driver 79 - * @open: called when the device file is opened 80 - * @release: release this open file 79 + * @open: called for a context when the device file is opened 80 + * @close_context: called when the device file is closed 81 + * @release: called to release the context 81 82 * @open_session: open a new session 82 83 * @close_session: close a session 83 84 * @system_session: declare session as a system session ··· 88 87 * @supp_send: called for supplicant to send a response 89 88 * @shm_register: register shared memory buffer in TEE 90 89 * @shm_unregister: unregister shared memory buffer in TEE 90 + * 91 + * The context given to @open might last longer than the device file if it is 92 + * tied to other resources in the TEE driver. @close_context is called when the 93 + * client closes the device file, even if there are existing references to the 94 + * context. The TEE driver can use @close_context to start cleaning up. 91 95 */ 92 96 struct tee_driver_ops { 93 97 void (*get_version)(struct tee_device *teedev, 94 98 struct tee_ioctl_version_data *vers); 95 99 int (*open)(struct tee_context *ctx); 100 + void (*close_context)(struct tee_context *ctx); 96 101 void (*release)(struct tee_context *ctx); 97 102 int (*open_session)(struct tee_context *ctx, 98 103 struct tee_ioctl_open_session_arg *arg, ··· 206 199 enum tee_dma_heap_id id, 207 200 struct tee_protmem_pool *pool); 208 201 void tee_device_put_all_dma_heaps(struct tee_device *teedev); 202 + 203 + /** 204 + * tee_device_get() - Increment the user count for a tee_device 205 + * @teedev: Pointer to the tee_device 206 + * 207 + * If tee_device_unregister() has been called and the final user of @teedev 208 + * has already released the device, this function will fail to prevent new users 209 + * from accessing the device during the unregistration process. 210 + * 211 + * Returns: true if @teedev remains valid, otherwise false 212 + */ 213 + bool tee_device_get(struct tee_device *teedev); 214 + 215 + /** 216 + * tee_device_put() - Decrease the user count for a tee_device 217 + * @teedev: pointer to the tee_device 218 + */ 219 + void tee_device_put(struct tee_device *teedev); 209 220 210 221 /** 211 222 * tee_device_set_dev_groups() - Set device attribute groups ··· 398 373 * @ctx: The struct tee_context to close 399 374 */ 400 375 void teedev_close_context(struct tee_context *ctx); 376 + 377 + /** 378 + * teedev_ctx_get() - Increment the reference count of a context 379 + * @ctx: Pointer to the context 380 + * 381 + * This function increases the refcount of the context, which is tied to 382 + * resources shared by the same tee_device. During the unregistration process, 383 + * the context may remain valid even after tee_device_unregister() has returned. 384 + * 385 + * Users should ensure that the context's refcount is properly decreased before 386 + * calling tee_device_put(), typically within the context's release() function. 387 + * Alternatively, users can call tee_device_get() and teedev_ctx_get() together 388 + * and release them simultaneously (see shm_alloc_helper()). 389 + */ 390 + void teedev_ctx_get(struct tee_context *ctx); 391 + 392 + /** 393 + * teedev_ctx_put() - Decrease reference count on a context 394 + * @ctx: pointer to the context 395 + */ 396 + void teedev_ctx_put(struct tee_context *ctx); 401 397 402 398 #endif /*__TEE_CORE_H*/