This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 47064e42df59e7ac4c41a289aff97989aa688df8 Author: George Poulios <gpoul...@census-labs.com> AuthorDate: Sat May 10 21:39:54 2025 +0300 drivers/misc/optee: Fix non-registered memory ref passing So far the NuttX implementation of OP-TEE has been using registered memory references to pass non-registered memory to OP-TEE OS, passing the physical address of the memory in what is normally used as a 'cookie'. This was compatible with the Openvela framework, but no other OP-TEE OS. Fix this by passing temporary memory instead with the standard non-contiguous (OPTEE_MSG_ATTR_NONCONTIG) flag. Signed-off-by: George Poulios <gpoul...@census-labs.com> --- drivers/misc/optee.c | 84 ++++++++++++++++++++++++++++++++-------------------- drivers/misc/optee.h | 1 + 2 files changed, 53 insertions(+), 32 deletions(-) diff --git a/drivers/misc/optee.c b/drivers/misc/optee.c index 427de42262..4803dd9542 100644 --- a/drivers/misc/optee.c +++ b/drivers/misc/optee.c @@ -562,48 +562,53 @@ static int optee_memref_to_msg_param(FAR struct optee_priv_data *priv, FAR const struct tee_ioctl_param *p) { FAR struct optee_shm *shm; + uintptr_t page_list_pa; - /* Warning: the case for non-registered memrefs below is a hack to work - * with openvela. Normally, non-registered memory should be specified as - * OPTEE_MSG_ATTR_TYPE_TMEM_* (note the 'T') and `buf_ptr` should be set - * to the physical address of buffer. - * - * Related openvela patches: - * - external_optee_optee_os@1a29df42 core/tee/entry_std.c#L160 - * - frameworks_security_optee_vela@54b377d5c compat/mobj_dyn_shm.c#L25 - * - * Ideally, in the future, this should be wrapped around some - * CONFIG_OPTEE_OPENVELA_COMPAT guard. - */ + if (p->c == TEE_MEMREF_NULL) + { + mp->attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT + p->attr - + TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; + mp->u.tmem.buf_ptr = 0; + mp->u.tmem.shm_ref = 0; + mp->u.tmem.size = p->b; + return 0; + } - mp->attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT + p->attr - - TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; - if (p->c != TEE_MEMREF_NULL) + shm = idr_find(priv->shms, p->c); + if (shm == NULL) { - shm = idr_find(priv->shms, p->c); - if (shm == NULL) - { - return -EINVAL; - } + return -EINVAL; + } - if (shm->flags & TEE_SHM_REGISTER) - { - mp->u.rmem.shm_ref = (uintptr_t)shm; - } - else - { - /* hack to comply with openvela */ + if (shm->flags & TEE_SHM_REGISTER) + { + /* registered memory */ - mp->u.rmem.shm_ref = shm->addr; - } + mp->attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT + p->attr - + TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; + mp->u.rmem.offs = p->a; + mp->u.rmem.size = p->b; + mp->u.rmem.shm_ref = (uintptr_t)shm; } else { - mp->u.rmem.shm_ref = 0; + /* non-registered memory (temporary) */ + + mp->attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT + p->attr - + TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; + mp->attr |= OPTEE_MSG_ATTR_NONCONTIG; + + shm->page_list = optee_shm_to_page_list(shm, &page_list_pa); + if (shm->page_list == NULL) + { + return -ENOMEM; + } + + mp->u.tmem.buf_ptr = page_list_pa; + mp->u.tmem.shm_ref = (uintptr_t)shm; + mp->u.tmem.size = shm->length; } - mp->u.rmem.size = p->b; - mp->u.rmem.offs = p->a; return 0; } @@ -666,6 +671,7 @@ static int optee_from_msg_param(FAR struct tee_ioctl_param *params, { FAR const struct optee_msg_param *mp = mparams + n; FAR struct tee_ioctl_param *p = params + n; + FAR struct optee_shm *shm; switch (mp->attr & OPTEE_MSG_ATTR_TYPE_MASK) { @@ -684,6 +690,20 @@ static int optee_from_msg_param(FAR struct tee_ioctl_param *params, p->b = mp->u.value.b; p->c = mp->u.value.c; break; + case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT: + case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT: + case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT: + p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT + + mp->attr - OPTEE_MSG_ATTR_TYPE_TMEM_INPUT; + p->b = mp->u.tmem.size; + + shm = (FAR struct optee_shm *)(uintptr_t)mp->u.tmem.shm_ref; + if (shm && shm->page_list) + { + kmm_free(shm->page_list); + shm->page_list = NULL; + } + break; case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT: case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT: case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT: diff --git a/drivers/misc/optee.h b/drivers/misc/optee.h index 27feb16664..57adf7180f 100644 --- a/drivers/misc/optee.h +++ b/drivers/misc/optee.h @@ -58,6 +58,7 @@ struct optee_shm int32_t id; uint64_t addr; uint64_t length; + FAR void *page_list; uint32_t flags; };