From: Arun Iyengar aiyengar1990@gmail.com
optee_supp_release() runs only on the context's last reference, which RPC shared memory can hold. If tee-supplicant exits during an RPC, the next request waits forever and a new tee-supplicant gets -EBUSY.
Detach the supplicant in .close_context instead.
Fixes: 217e0250cccb ("tee: use reference counting for tee_context") Signed-off-by: Arun Iyengar aiyengar1990@gmail.com --- Tested on an Orange Pi 5 (RK3588S, SMC ABI), 7.3-based KASAN + lockdep kernel: tee-supplicant stopped and restarted during fTPM NV writes, no hung task; the fTPM TA then stays dead until a reboot. FF-A is build-tested only.
Developed with Claude (Anthropic), which wrote the code and the commit message. I reviewed it. --- drivers/tee/optee/core.c | 4 +--- drivers/tee/optee/ffa_abi.c | 3 ++- drivers/tee/optee/optee_private.h | 2 +- drivers/tee/optee/smc_abi.c | 3 ++- 4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index a52c1f498b99..f446b40d7827 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -184,12 +184,10 @@ void optee_release(struct tee_context *ctx) optee_release_helper(ctx, optee_close_session_helper); }
-void optee_release_supp(struct tee_context *ctx) +void optee_close_context_supp(struct tee_context *ctx) { struct optee *optee = tee_get_drvdata(ctx->teedev);
- optee_release_helper(ctx, optee_close_session_helper); - optee_supp_release(&optee->supp); }
diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c index 702da7d98fbc..155ce9856de9 100644 --- a/drivers/tee/optee/ffa_abi.c +++ b/drivers/tee/optee/ffa_abi.c @@ -957,7 +957,8 @@ static const struct tee_driver_ops optee_ffa_supp_ops = { .get_version = optee_ffa_get_version, .get_tee_revision = optee_get_revision, .open = optee_ffa_open, - .release = optee_release_supp, + .close_context = optee_close_context_supp, + .release = optee_release, .supp_recv = optee_supp_recv, .supp_send = optee_supp_send, .shm_register = optee_ffa_shm_register, /* same as for clnt ops */ diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h index 94a4f251f5cf..6495e0f07deb 100644 --- a/drivers/tee/optee/optee_private.h +++ b/drivers/tee/optee/optee_private.h @@ -370,7 +370,7 @@ void optee_set_dev_group(struct optee *optee); void optee_remove_common(struct optee *optee); int optee_open(struct tee_context *ctx, bool cap_memref_null); void optee_release(struct tee_context *ctx); -void optee_release_supp(struct tee_context *ctx); +void optee_close_context_supp(struct tee_context *ctx);
static inline void optee_from_msg_param_value(struct tee_param *p, u32 attr, const struct optee_msg_param *mp) diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c index 51624443359b..0278dc6b0119 100644 --- a/drivers/tee/optee/smc_abi.c +++ b/drivers/tee/optee/smc_abi.c @@ -1264,7 +1264,8 @@ static const struct tee_driver_ops optee_supp_ops = { .get_version = optee_get_version, .get_tee_revision = optee_get_revision, .open = optee_smc_open, - .release = optee_release_supp, + .close_context = optee_close_context_supp, + .release = optee_release, .supp_recv = optee_supp_recv, .supp_send = optee_supp_send, .shm_register = optee_shm_register_supp,
--- base-commit: e21989d08e0d6abacfff71387d0cb36dd96a4079 change-id: 20261115-optee-supp-close-45df0ffe66b3
Best regards, -- Arun Iyengar aiyengar1990@gmail.com