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;
 }

Reply via email to