This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit a5d3627bef8446bb92222fae4c12c802779bc60e Author: hujun5 <[email protected]> AuthorDate: Tue Nov 10 13:22:51 2026 +0800 drivers/tee/optee: Allocate shared memory from RPMsg area Allocate shared memory from the RPMsg shared-memory area and add a callback for map-memory allocation. Remove the obsolete compatibility configuration, register shared memory, and fix address types to avoid compile-time warnings. Signed-off-by: hujun5 <[email protected]> --- drivers/misc/optee.c | 99 +++++++++++++++++++++++++++++++++++---------- drivers/misc/optee.h | 19 ++++++++- drivers/misc/optee_rpc.c | 8 ++-- drivers/misc/optee_smc.c | 9 +++++ drivers/misc/optee_socket.c | 52 +++++------------------- 5 files changed, 119 insertions(+), 68 deletions(-) diff --git a/drivers/misc/optee.c b/drivers/misc/optee.c index a5cd9b2e6b4..6150bbc8fea 100644 --- a/drivers/misc/optee.c +++ b/drivers/misc/optee.c @@ -24,6 +24,7 @@ * Included Files ****************************************************************************/ +#include <unistd.h> #include <fcntl.h> #include <nuttx/tee.h> #include <nuttx/nuttx.h> @@ -32,13 +33,13 @@ #include <nuttx/fs/fs.h> #include <nuttx/kmalloc.h> #include <nuttx/lib/math32.h> +#include <nuttx/sched.h> #include <sys/mman.h> #include <sys/param.h> #ifdef CONFIG_ARCH_ADDRENV # include <nuttx/addrenv.h> # include <nuttx/pgalloc.h> -# include <nuttx/sched.h> # include <nuttx/arch.h> #endif @@ -331,8 +332,10 @@ static int optee_shm_register(FAR struct optee_priv_data *priv, FAR struct optee_shm *shm) { FAR struct optee_msg_arg *msg; - uintptr_t page_list_pa; + uintptr_t page_list_pa = 0; +#ifdef CONFIG_BUILD_KERNEL FAR void *page_list; +#endif int ret = -ENOMEM; optee_msg_alloc(priv, 1, msg); @@ -341,15 +344,21 @@ static int optee_shm_register(FAR struct optee_priv_data *priv, return -ENOMEM; } +#ifdef CONFIG_BUILD_KERNEL page_list = optee_shm_to_page_list(shm, &page_list_pa); if (page_list == NULL) { goto errout_with_msg; } +#else + page_list_pa = shm->paddr; +#endif msg->cmd = OPTEE_MSG_CMD_REGISTER_SHM; - msg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT | - OPTEE_MSG_ATTR_NONCONTIG; + msg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT; +#ifdef CONFIG_BUILD_KERNEL + msg->params[0].attr |= OPTEE_MSG_ATTR_NONCONTIG; +#endif msg->params[0].u.tmem.buf_ptr = page_list_pa; msg->params[0].u.tmem.shm_ref = (uintptr_t)shm; msg->params[0].u.tmem.size = shm->length; @@ -366,8 +375,10 @@ static int optee_shm_register(FAR struct optee_priv_data *priv, } errout_with_list: +#ifdef CONFIG_BUILD_KERNEL kmm_free(page_list); errout_with_msg: +#endif optee_msg_free(priv, msg); return ret; } @@ -421,6 +432,23 @@ errout_with_msg: return ret; } +static int optee_shm_munmap(FAR struct task_group_s *group, + FAR struct mm_map_entry_s *entry, + FAR void *start, + size_t length) +{ + FAR struct optee_shm *shm = (FAR struct optee_shm *)entry->priv.p; + int ret; + + DEBUGASSERT(shm != NULL); + + entry->priv.p = shm->p; + ret = shm->munmap(group, entry, start, length); + + optee_shm_free(shm); + return ret; +} + /**************************************************************************** * Name: optee_shm_close * @@ -439,7 +467,7 @@ static int optee_shm_close(FAR struct file *filep) { FAR struct optee_shm *shm = filep->f_priv; - if (shm != NULL && shm->id > -1) + if (shm != NULL && shm->id > -1 && shm->munmap == NULL) { filep->f_priv = NULL; optee_shm_free(shm); @@ -467,6 +495,8 @@ static int optee_shm_mmap(FAR struct file *filep, FAR struct mm_map_entry_s *map) { FAR struct optee_shm *shm = filep->f_priv; + FAR struct optee_priv_data *priv = shm->priv; + FAR struct mm_map_entry_s *entry; int32_t ret = OK; if ((map->flags & MAP_PRIVATE) && (map->flags & MAP_SHARED)) @@ -490,13 +520,30 @@ static int optee_shm_mmap(FAR struct file *filep, return -EINVAL; } - ret = map_anonymous(map, false); + ret = optee_transport_mmap(priv, map, shm); if (ret == OK) { DEBUGASSERT(map->vaddr != NULL); - shm->vaddr = (uint64_t)map->vaddr; + shm->vaddr = (uintptr_t)map->vaddr; shm->paddr = optee_va_to_pa(map->vaddr); + shm->flags |= TEE_SHM_REGISTER; + + entry = mm_map_find(get_current_mm(), map->vaddr, map->length); + DEBUGASSERT(entry != NULL); + + shm->munmap = entry->munmap; + entry->munmap = optee_shm_munmap; + shm->p = entry->priv.p; + entry->priv.p = shm; + + ret = optee_shm_register(priv, shm); + if (ret < 0) + { + shm->munmap(this_task()->group, entry, + entry->vaddr, entry->length); + optee_shm_free(shm); + } } return ret; @@ -579,13 +626,21 @@ static int optee_close(FAR struct file *filep) idr_for_each_entry(priv->shms, shm, id) { /* Here, we only free, unfreed kernel allocations, the rest will be - * done by optee_shm_close(). + * done by optee_shm_munmap()/optee_shm_close(). */ if (shm->fd == -1) { optee_shm_free(shm); } + else + { + /* The content recorded in priv is about to become invalid; + * we set shm->priv = NULL here + */ + + shm->priv = NULL; + } } idr_destroy(priv->shms); @@ -605,7 +660,7 @@ 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; + uintptr_t page_list_pa = 0; bool external_vm_context = false; if (p->c == TEE_MEMREF_NULL) @@ -882,13 +937,15 @@ optee_ioctl_close_session(FAR struct optee_priv_data *priv, return optee_close_session(priv, arg->session); } -static int optee_ioctl_version(FAR struct tee_ioctl_version_data *vers) +static int optee_ioctl_version(FAR struct optee_priv_data *priv, + FAR struct tee_ioctl_version_data *vers) { + vers->gen_caps |= priv->capabilities; vers->impl_id = TEE_IMPL_ID_OPTEE; vers->impl_caps = TEE_OPTEE_CAP_TZ; vers->gen_caps = TEE_GEN_CAP_GP | - TEE_GEN_CAP_MEMREF_NULL | - TEE_GEN_CAP_REG_MEM; + TEE_GEN_CAP_MEMREF_NULL; + return 0; } @@ -958,7 +1015,7 @@ optee_shm_register_supplicant(FAR struct optee_priv_data *priv, FAR struct optee_shm **shmp) { FAR struct optee_shm *shm; - uintptr_t page_list_pa; + uintptr_t page_list_pa = 0; int ret = 0; shm = kmm_zalloc(sizeof(struct optee_shm)); @@ -1107,9 +1164,9 @@ optee_ioctl_supplicant_recv(FAR struct optee_priv_data *priv, p->c = (uint64_t)-1; /* Invalid shm id. */ break; } - break; - default: - break; + break; + default: + break; } } @@ -1179,7 +1236,7 @@ static int optee_ioctl(FAR struct file *filep, int cmd, unsigned long arg) switch (cmd) { case TEE_IOC_VERSION: - return optee_ioctl_version(parg); + return optee_ioctl_version(priv, parg); case TEE_IOC_OPEN_SESSION: return optee_ioctl_open_session(priv, parg); case TEE_IOC_INVOKE: @@ -1600,10 +1657,10 @@ int optee_from_msg_param(FAR struct tee_ioctl_param *params, } #ifndef CONFIG_ARCH_USE_MMU - if (shm) - { - up_invalidate_dcache(shm->vaddr, shm->vaddr + shm->length); - } + if (shm) + { + up_invalidate_dcache(shm->vaddr, shm->vaddr + shm->length); + } #endif } diff --git a/drivers/misc/optee.h b/drivers/misc/optee.h index 31776dd0c97..855cd4d8c84 100644 --- a/drivers/misc/optee.h +++ b/drivers/misc/optee.h @@ -31,6 +31,7 @@ #include <nuttx/compiler.h> #include <nuttx/tee.h> #include <nuttx/idr.h> +#include <nuttx/mm/map.h> #include "optee_msg.h" @@ -73,6 +74,7 @@ struct optee_priv_data uintptr_t alignment; /* Transport-specified message alignment */ FAR struct idr_s *shms; /* An RB tree of process local shm entries */ enum optee_role_e role; + uint32_t capabilities; }; struct optee_shm @@ -80,11 +82,20 @@ struct optee_shm FAR struct optee_priv_data *priv; int fd; int32_t id; - uint64_t vaddr; - uint64_t paddr; + uintptr_t vaddr; + uintptr_t paddr; uint64_t length; FAR void *page_list; uint32_t flags; + + /* used to store real priv */ + + FAR void *p; + + int (*munmap)(FAR struct task_group_s *group, + FAR struct mm_map_entry_s *entry, + FAR void *start, + size_t length); }; /**************************************************************************** @@ -112,6 +123,10 @@ void optee_transport_close(FAR struct optee_priv_data *priv); int optee_transport_call(FAR struct optee_priv_data *priv, FAR struct optee_msg_arg *arg); +int optee_transport_mmap(FAR struct optee_priv_data *priv, + FAR struct mm_map_entry_s *entry, + FAR struct optee_shm *shm); + int optee_from_msg_param(FAR struct tee_ioctl_param *params, size_t num_params, FAR const struct optee_msg_param *mparams); diff --git a/drivers/misc/optee_rpc.c b/drivers/misc/optee_rpc.c index 1307ec97c24..3566aee0dc0 100644 --- a/drivers/misc/optee_rpc.c +++ b/drivers/misc/optee_rpc.c @@ -254,11 +254,11 @@ static void optee_rpc_cmd_shm_free(FAR struct optee_priv_data *priv, #ifdef CONFIG_DEV_OPTEE_SUPPLICANT arg->ret = optee_supplicant_free(shm->id); if (arg->ret) - { - /* The supplicant either failed or isn't running. */ + { + /* The supplicant either failed or isn't running. */ - return; - } + return; + } #else arg->ret = TEE_ERROR_NOT_SUPPORTED; return; diff --git a/drivers/misc/optee_smc.c b/drivers/misc/optee_smc.c index bff5a041cd7..2e29880691a 100644 --- a/drivers/misc/optee_smc.c +++ b/drivers/misc/optee_smc.c @@ -25,6 +25,7 @@ ****************************************************************************/ #include <nuttx/cache.h> +#include <nuttx/fs/fs.h> #include <nuttx/kmalloc.h> #include <errno.h> #include <syslog.h> @@ -278,6 +279,7 @@ int optee_transport_open(FAR struct optee_priv_data **priv_) priv->base.alignment = OPTEE_MSG_NONCONTIG_PAGE_SIZE; priv->smc_fn = smc_conduit; + priv->base.capabilities |= TEE_GEN_CAP_REG_MEM; *priv_ = (FAR struct optee_priv_data *)priv; return 0; } @@ -362,3 +364,10 @@ int optee_transport_call(FAR struct optee_priv_data *priv_, } } } + +int optee_transport_mmap(FAR struct optee_priv_data *priv, + FAR struct mm_map_entry_s *entry, + FAR struct optee_shm *shm) +{ + return map_anonymous(entry, false); +} diff --git a/drivers/misc/optee_socket.c b/drivers/misc/optee_socket.c index c4fe1c9f446..a13899ac85d 100644 --- a/drivers/misc/optee_socket.c +++ b/drivers/misc/optee_socket.c @@ -65,6 +65,7 @@ static int optee_socket_recv(FAR struct socket *psock, FAR void *msg, while (size > 0) { ssize_t n = psock_recv(psock, msg, size, 0); + if (n <= 0) { return n < 0 ? n : -EIO; @@ -77,6 +78,16 @@ static int optee_socket_recv(FAR struct socket *psock, FAR void *msg, return 0; } +int optee_transport_mmap(FAR struct optee_priv_data *priv_, + FAR struct mm_map_entry_s *entry, + FAR struct optee_shm *shm) +{ + FAR struct optee_socket_priv_data *priv = + (FAR struct optee_socket_priv_data *)priv_; + + return psock_mmap(&priv->socket, entry); +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -208,46 +219,22 @@ int optee_transport_call(FAR struct optee_priv_data *priv_, FAR struct optee_msg_arg *arg) { /* iov[0]: struct opteee_msg_arg + struct optee_msg_param[n] - * iov[1 - n+1]: shm_mem * 0 <= n <= 6 */ FAR struct optee_socket_priv_data *priv = (FAR struct optee_socket_priv_data *)priv_; size_t arg_size = OPTEE_MSG_GET_ARG_SIZE(arg->num_params); - size_t shm_size[OPTEE_MAX_PARAM_NUM]; - size_t shm_addr[OPTEE_MAX_PARAM_NUM]; struct iovec iov[OPTEE_SOCKET_MAX_IOVEC_NUM]; struct msghdr msghdr; unsigned long iovlen = 1; - unsigned long i; int ret; memset(iov, 0, sizeof(iov)); - memset(shm_size, 0, sizeof(shm_size)); iov[0].iov_base = arg; iov[0].iov_len = arg_size; - for (i = 0; i < arg->num_params; i++) - { - if (arg->params[i].attr == OPTEE_MSG_ATTR_TYPE_RMEM_INPUT || - arg->params[i].attr == OPTEE_MSG_ATTR_TYPE_RMEM_INOUT) - { - iov[iovlen].iov_base = - (FAR void *)(uintptr_t)arg->params[i].u.rmem.shm_ref; - iov[iovlen].iov_len = arg->params[i].u.rmem.size; - shm_size[i] = arg->params[i].u.rmem.size; - shm_addr[i] = arg->params[i].u.rmem.shm_ref; - iovlen++; - } - else if (arg->params[i].attr == OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT) - { - shm_size[i] = arg->params[i].u.rmem.size; - shm_addr[i] = arg->params[i].u.rmem.shm_ref; - } - } - memset(&msghdr, 0, sizeof(struct msghdr)); msghdr.msg_iov = iov; msghdr.msg_iovlen = iovlen; @@ -264,22 +251,5 @@ int optee_transport_call(FAR struct optee_priv_data *priv_, return ret; } - for (i = 0; i < arg->num_params; i++) - { - if (arg->params[i].attr == OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT || - arg->params[i].attr == OPTEE_MSG_ATTR_TYPE_RMEM_INOUT) - { - size_t size = MIN(arg->params[i].u.rmem.size, shm_size[i]); - arg->params[i].u.rmem.shm_ref = shm_addr[i]; - ret = optee_socket_recv(&priv->socket, - (FAR void *)(uintptr_t) - arg->params[i].u.rmem.shm_ref, size); - if (ret < 0) - { - return ret; - } - } - } - return 0; }
