xiaoxiang781216 commented on code in PR #16734: URL: https://github.com/apache/nuttx/pull/16734#discussion_r2233639641
########## drivers/misc/optee.c: ########## @@ -589,27 +572,33 @@ static int optee_open(FAR struct file *filep) static int optee_close(FAR struct file *filep) { FAR struct optee_priv_data *priv = filep->f_priv; +#ifdef CONFIG_DEV_OPTEE_SUPPLICANT + enum optee_role_e role = (uintptr_t)filep->f_inode->i_private; Review Comment: remove, check priv->role instead ########## drivers/misc/optee.c: ########## @@ -1103,6 +1049,121 @@ optee_ioctl_shm_register(FAR struct optee_priv_data *priv, return ret; } +#ifdef CONFIG_DEV_OPTEE_SUPPLICANT +static int +optee_ioctl_supplicant_recv(FAR struct optee_priv_data *priv, + FAR struct tee_ioctl_buf_data *data) +{ + int n; + int ret; + FAR struct tee_iocl_supp_recv_arg *arg; + + if (!optee_is_valid_range(data, sizeof(*data))) + { + return -EFAULT; + } + + if (!optee_is_valid_range((FAR void *)data->buf_ptr, data->buf_len)) + { + return -EFAULT; + } + + if (data->buf_len > TEE_MAX_ARG_SIZE || + data->buf_len < sizeof(struct tee_iocl_supp_recv_arg)) + { + return -EINVAL; + } + + arg = (FAR struct tee_iocl_supp_recv_arg *)(uintptr_t)data->buf_ptr; + + if (sizeof(*arg) + TEE_IOCTL_PARAM_SIZE(arg->num_params) != + data->buf_len) + { + return -EINVAL; + } + + if (arg->num_params > OPTEE_MAX_PARAM_NUM) + { + return -EINVAL; + } + + ret = optee_supplicant_recv(&arg->func, &arg->num_params, arg->params); + + if (ret < 0) + { + goto out; + } + + for (n = 0; n < arg->num_params; n++) + { + FAR struct tee_ioctl_param *p = arg->params + n; + + switch (p->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) + { + case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT: + case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT: + break; + case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT: + case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT: + case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT: + if (!p->b) + { + p->a = 0; + p->c = (uint64_t)-1; /* invalid shm id */ + break; + } + break; + default: + break; + } + } + +out: + return ret; +} + +static int +optee_ioctl_supplicant_send(FAR struct optee_priv_data *priv, + FAR struct tee_ioctl_buf_data *data) Review Comment: remove extra space before `*data` ########## drivers/misc/optee_rpc.c: ########## @@ -0,0 +1,362 @@ +/**************************************************************************** + * drivers/misc/optee_rpc.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/signal.h> +#include <nuttx/kmalloc.h> +#include <stdint.h> + +#include "optee.h" +#include "optee_msg.h" +#include "optee_rpc.h" + +#ifdef CONFIG_DEV_OPTEE_SUPPLICANT +# include "optee_supplicant.h" +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: optee_rpc_cmd_get_time + * + * Description: + * Return REE wall-clock time (seconds + nanoseconds) to secure world. + * + * Parameters: + * arg - Pointer to the RPC message argument located in shared memory by + * the secure world. The answer will be placed in the same argument. + * + * Returned Value: + * The time is written to: + * arg->params[0].u.value.a containing seconds since epoch + * arg->params[0].u.value.b containing nanoseconds + * Result code is written to arg->ret. + * + ****************************************************************************/ + +static void optee_rpc_cmd_get_time(FAR struct optee_msg_arg *arg) +{ + struct timespec ts; + + /* OP-TEE parameter validation. */ + + if (arg->num_params != 1 || + (arg->params[0].attr & OPTEE_MSG_ATTR_TYPE_MASK) + != OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT) + { + arg->ret = TEE_ERROR_BAD_PARAMETERS; + return; + } + + if (clock_gettime(CLOCK_REALTIME, &ts) < 0) + { + /* Should not happen unless the RTC driver is missing */ + + arg->ret = TEE_ERROR_GENERIC; + return; + } + + arg->params[0].u.value.a = (uint32_t)ts.tv_sec; /* Seconds since epoch. */ + arg->params[0].u.value.b = (uint32_t)ts.tv_nsec; /* Nanoseconds. */ + + arg->ret = TEE_SUCCESS; +} + +/**************************************************************************** + * Name: optee_rpc_cmd_suspend + * + * Description: + * Request from OP-TEE to suspend the current nuttx process. + * + * Parameters: + * arg - Pointer to the RPC message argument, located in a shared page, by + * the secure world, containing the time in msec to sleep. + * + * Returned Value: + * None. Result codes are written into arg->ret. + * + ****************************************************************************/ + +static void optee_rpc_cmd_suspend(FAR struct optee_msg_arg *arg) +{ + useconds_t usec_to_wait; + + /* OP-TEE parameter validation. */ + + if (arg->num_params != 1 || + (arg->params[0].attr & OPTEE_MSG_ATTR_TYPE_MASK) != + OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) + { + arg->ret = TEE_ERROR_BAD_PARAMETERS; + return; + } + + usec_to_wait = arg->params[0].u.value.a * 1000; + + if (usec_to_wait) + { + int ret = nxsig_usleep(usec_to_wait); + + if (ret < 0 && ret != EINTR) + { + arg->ret = TEE_ERROR_GENERIC; + return; + } + } + + arg->ret = TEE_SUCCESS; +} + +/**************************************************************************** + * Name: optee_rpc_cmd_shm_alloc + * + * Description: + * Handle OP-TEE's RPC to allocate shared memory. + * + * Parameters: + * priv - Pointer to the driver's optee_priv_data struct. + * arg - Pointer to the RPC message argument, located in a shared page + * by the secure world. A copy of this message might be sent to the + * supplicant process that runs in userspace for further processing. + * last_page_list - Passes by reference a pointer that will be updated with + * the virtual address of the page list. + * + * Returned Value: + * None. Result codes are written into arg->ret. + * Information about the shared memory is passed through arg->params + * + ****************************************************************************/ + +static void optee_rpc_cmd_shm_alloc(FAR struct optee_priv_data *priv, + FAR struct optee_msg_arg *arg, + FAR void **last_page_list) +{ + FAR struct optee_shm *shm; + size_t n; + size_t size; + int32_t ret = -ENOTTY; + + arg->ret_origin = TEE_ORIGIN_COMMS; + + /* OP-TEE parameter validation. */ + + if (arg->num_params != 1 || + arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) + { + arg->ret = TEE_ERROR_BAD_PARAMETERS; + return; + } + + for (n = 1; n < arg->num_params; n++) Review Comment: remove, impossible to enter the loop since the check at line 167 ########## drivers/misc/optee_rpc.c: ########## @@ -199,24 +198,9 @@ static void optee_rpc_cmd_shm_alloc(FAR struct optee_priv_data *priv, break; } - if (ret == -ENOMEM) + arg->ret = optee_convert_from_errno(ret); + if (arg->ret != TEE_SUCCESS) Review Comment: remove line 224 ########## drivers/misc/optee_supplicant.h: ########## @@ -0,0 +1,71 @@ +/**************************************************************************** + * drivers/misc/optee_supplicant.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __DRIVERS_MISC_OPTEE_SUPPLICANT_H +#define __DRIVERS_MISC_OPTEE_SUPPLICANT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <sys/types.h> Review Comment: add blank line ########## drivers/misc/optee.c: ########## @@ -1218,15 +1254,16 @@ int optee_shm_alloc(FAR struct optee_priv_data *priv, FAR void *addr, ptr = addr; } - if (ptr == NULL) + if (!(flags & TEE_SHM_USER_MAP) && + (ptr == NULL)) Review Comment: remove () and merge to previous line ########## drivers/misc/optee.c: ########## @@ -1103,6 +1049,121 @@ optee_ioctl_shm_register(FAR struct optee_priv_data *priv, return ret; } +#ifdef CONFIG_DEV_OPTEE_SUPPLICANT +static int +optee_ioctl_supplicant_recv(FAR struct optee_priv_data *priv, + FAR struct tee_ioctl_buf_data *data) +{ + int n; + int ret; + FAR struct tee_iocl_supp_recv_arg *arg; + + if (!optee_is_valid_range(data, sizeof(*data))) + { + return -EFAULT; + } + + if (!optee_is_valid_range((FAR void *)data->buf_ptr, data->buf_len)) + { + return -EFAULT; + } + + if (data->buf_len > TEE_MAX_ARG_SIZE || + data->buf_len < sizeof(struct tee_iocl_supp_recv_arg)) + { + return -EINVAL; + } + + arg = (FAR struct tee_iocl_supp_recv_arg *)(uintptr_t)data->buf_ptr; + + if (sizeof(*arg) + TEE_IOCTL_PARAM_SIZE(arg->num_params) != + data->buf_len) + { + return -EINVAL; + } + + if (arg->num_params > OPTEE_MAX_PARAM_NUM) + { + return -EINVAL; + } + + ret = optee_supplicant_recv(&arg->func, &arg->num_params, arg->params); + + if (ret < 0) + { + goto out; Review Comment: return directly and remove out label ########## drivers/misc/optee.c: ########## @@ -1103,6 +1049,121 @@ optee_ioctl_shm_register(FAR struct optee_priv_data *priv, return ret; } +#ifdef CONFIG_DEV_OPTEE_SUPPLICANT +static int +optee_ioctl_supplicant_recv(FAR struct optee_priv_data *priv, + FAR struct tee_ioctl_buf_data *data) +{ + int n; + int ret; + FAR struct tee_iocl_supp_recv_arg *arg; + + if (!optee_is_valid_range(data, sizeof(*data))) + { + return -EFAULT; + } + + if (!optee_is_valid_range((FAR void *)data->buf_ptr, data->buf_len)) + { + return -EFAULT; + } + + if (data->buf_len > TEE_MAX_ARG_SIZE || + data->buf_len < sizeof(struct tee_iocl_supp_recv_arg)) + { + return -EINVAL; + } + + arg = (FAR struct tee_iocl_supp_recv_arg *)(uintptr_t)data->buf_ptr; + + if (sizeof(*arg) + TEE_IOCTL_PARAM_SIZE(arg->num_params) != + data->buf_len) + { + return -EINVAL; + } + + if (arg->num_params > OPTEE_MAX_PARAM_NUM) + { + return -EINVAL; + } + + ret = optee_supplicant_recv(&arg->func, &arg->num_params, arg->params); + + if (ret < 0) + { + goto out; + } + + for (n = 0; n < arg->num_params; n++) + { + FAR struct tee_ioctl_param *p = arg->params + n; + + switch (p->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) + { + case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT: + case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT: + break; + case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT: + case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT: + case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT: + if (!p->b) + { + p->a = 0; + p->c = (uint64_t)-1; /* invalid shm id */ + break; + } + break; + default: + break; + } + } + +out: + return ret; +} + +static int +optee_ioctl_supplicant_send(FAR struct optee_priv_data *priv, + FAR struct tee_ioctl_buf_data *data) +{ + int ret; + FAR struct tee_iocl_supp_send_arg *arg; + + if (!optee_is_valid_range(data, sizeof(*data))) + { + return -EFAULT; + } + + if (!optee_is_valid_range((FAR void *)data->buf_ptr, data->buf_len)) + { + return -EFAULT; + } + + if (data->buf_len > TEE_MAX_ARG_SIZE || + data->buf_len < sizeof(struct tee_iocl_supp_send_arg)) + { + return -EINVAL; + } + + arg = (FAR struct tee_iocl_supp_send_arg *)(uintptr_t)data->buf_ptr; + + if (sizeof(*arg) + TEE_IOCTL_PARAM_SIZE(arg->num_params) != + data->buf_len) + { + return -EINVAL; + } + + if (arg->num_params > OPTEE_MAX_PARAM_NUM) + { + return -EINVAL; + } + + ret = optee_supplicant_send(arg->ret, arg->num_params, arg->params); Review Comment: return directly and remove line 1129 ########## drivers/misc/optee_supplicant.h: ########## @@ -0,0 +1,71 @@ +/**************************************************************************** + * drivers/misc/optee_supplicant.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __DRIVERS_MISC_OPTEE_SUPPLICANT_H +#define __DRIVERS_MISC_OPTEE_SUPPLICANT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <sys/types.h> +#include "optee.h" + +/**************************************************************************** + * Public Functions Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +void optee_supplicant_init(FAR struct idr_s **shm_idr); +void optee_supplicant_uninit(void); + +FAR struct optee_shm *optee_supplicant_search_shm(uint32_t id); + +uint32_t optee_supplicant_request(uint32_t func, uint32_t num_params, + FAR struct tee_ioctl_param *param); + +uint32_t optee_supplicant_cmd_free(int32_t shm_id); +int optee_supplicant_cmd_alloc(FAR struct optee_priv_data *priv, Review Comment: let's remove cmd_ from alloc/free? ########## drivers/misc/optee_supplicant.c: ########## @@ -0,0 +1,608 @@ +/**************************************************************************** + * drivers/misc/optee_supplicant.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/mutex.h> +#include <nuttx/semaphore.h> +#include <nuttx/kmalloc.h> +#include <nuttx/queue.h> +#include <nuttx/idr.h> +#include <string.h> + +#include "optee.h" +#include "optee_supplicant.h" +#include "optee_msg.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Request structure for RPCs serviced by the supplicant. */ + +struct optee_supplicant_req +{ + sq_entry_t link; + uint32_t func; + uint32_t ret; + uint32_t num_params; + FAR struct tee_ioctl_param *params; + sem_t c; +}; + +struct optee_supplicant +{ + mutex_t mutex; + int req_id; + struct sq_queue_s reqs; + FAR struct idr_s *idr; + FAR struct idr_s *shm_idr; + sem_t reqs_c; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct optee_supplicant g_optee_supp; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pop_entry + * + * Description: + * Pop the first request from the request queue, and create unique id. + * + * Parameters: + * num_params - Number of parameters passed. + * id - Pointer to the unique request id. + * + * Returned Value: + * A pointer to the request on success or NULL. + * + ****************************************************************************/ + +static FAR struct optee_supplicant_req * pop_entry(uint32_t num_params, + FAR int *id) +{ + FAR struct optee_supplicant_req *req; + + if (g_optee_supp.req_id != -1) + { + /* Mixing sync/async not supported */ + + return NULL; + } + + if (sq_empty(&g_optee_supp.reqs)) + { + return NULL; + } + + req = (struct optee_supplicant_req *)sq_remfirst(&g_optee_supp.reqs); Review Comment: add FAR ########## drivers/misc/optee_supplicant.c: ########## @@ -0,0 +1,608 @@ +/**************************************************************************** + * drivers/misc/optee_supplicant.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/mutex.h> +#include <nuttx/semaphore.h> +#include <nuttx/kmalloc.h> +#include <nuttx/queue.h> +#include <nuttx/idr.h> +#include <string.h> + +#include "optee.h" +#include "optee_supplicant.h" +#include "optee_msg.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Request structure for RPCs serviced by the supplicant. */ + +struct optee_supplicant_req +{ + sq_entry_t link; + uint32_t func; + uint32_t ret; + uint32_t num_params; + FAR struct tee_ioctl_param *params; + sem_t c; +}; + +struct optee_supplicant +{ + mutex_t mutex; + int req_id; + struct sq_queue_s reqs; + FAR struct idr_s *idr; + FAR struct idr_s *shm_idr; + sem_t reqs_c; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct optee_supplicant g_optee_supp; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pop_entry + * + * Description: + * Pop the first request from the request queue, and create unique id. + * + * Parameters: + * num_params - Number of parameters passed. + * id - Pointer to the unique request id. + * + * Returned Value: + * A pointer to the request on success or NULL. + * + ****************************************************************************/ + +static FAR struct optee_supplicant_req * pop_entry(uint32_t num_params, + FAR int *id) +{ + FAR struct optee_supplicant_req *req; + + if (g_optee_supp.req_id != -1) + { + /* Mixing sync/async not supported */ + + return NULL; + } + + if (sq_empty(&g_optee_supp.reqs)) + { + return NULL; + } + + req = (struct optee_supplicant_req *)sq_remfirst(&g_optee_supp.reqs); + + /* The request can't fit in the supplicant's supplied parameter buffer. */ + + if (num_params < req->num_params) + { + return NULL; + } + + *id = idr_alloc(g_optee_supp.idr, req, 0, INT32_MAX); + if (*id < 0) + { + return NULL; + } + + return req; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: optee_supplicant_init + * + * Description: + * Initialize supplicant data. + * + * Parameters: + * shm_idr - A pointer, passed by reference, to the optee driver's shm_idr. + * The destruction of the shm_idr will be handled by + * optee_close(), so we only need to initialize it in this + * context. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void optee_supplicant_init(FAR struct idr_s **shm_idr) +{ + memset(&g_optee_supp, 0, sizeof(g_optee_supp)); + nxmutex_init(&g_optee_supp.mutex); + nxsem_init(&g_optee_supp.reqs_c, 0, 0); + sq_init(&g_optee_supp.reqs); + g_optee_supp.idr = idr_init(); + g_optee_supp.shm_idr = idr_init(); + *shm_idr = g_optee_supp.shm_idr; + g_optee_supp.req_id = -1; +} + +/**************************************************************************** + * Name: optee_supplicant_uninit + * + * Description: + * Uninitialize supplicant data. + * + * Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void optee_supplicant_uninit(void) +{ + /* The destruction of the idr_s is performed by optee_close(). */ + + g_optee_supp.shm_idr = NULL; + nxmutex_destroy(&g_optee_supp.mutex); + nxsem_destroy(&g_optee_supp.reqs_c); + idr_destroy(g_optee_supp.idr); +} + +/**************************************************************************** + * Name: optee_supplicant_request + * + * Description: + * Create a request with the received parameters from the OP-TEE, add it to + * the supplicant's request queue and then wait on the request's semaphore + * until it is serviced. + * + * Parameters: + * func - Requested function for the supplicant to perform + * params - Pointer pointer to parameter data. + * num_params - Number of parameters passed. + * + * Returned Value: + * TEE_SUCCESS on success or a global platform api error code on failure. + * + ****************************************************************************/ + +uint32_t optee_supplicant_request(uint32_t func, uint32_t num_params, Review Comment: change to static function and move to private section ########## drivers/misc/optee_rpc.c: ########## @@ -0,0 +1,362 @@ +/**************************************************************************** + * drivers/misc/optee_rpc.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/signal.h> +#include <nuttx/kmalloc.h> +#include <stdint.h> + +#include "optee.h" +#include "optee_msg.h" +#include "optee_rpc.h" + +#ifdef CONFIG_DEV_OPTEE_SUPPLICANT +# include "optee_supplicant.h" +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: optee_rpc_cmd_get_time + * + * Description: + * Return REE wall-clock time (seconds + nanoseconds) to secure world. + * + * Parameters: + * arg - Pointer to the RPC message argument located in shared memory by + * the secure world. The answer will be placed in the same argument. + * + * Returned Value: + * The time is written to: + * arg->params[0].u.value.a containing seconds since epoch + * arg->params[0].u.value.b containing nanoseconds + * Result code is written to arg->ret. + * + ****************************************************************************/ + +static void optee_rpc_cmd_get_time(FAR struct optee_msg_arg *arg) +{ + struct timespec ts; + + /* OP-TEE parameter validation. */ + + if (arg->num_params != 1 || + (arg->params[0].attr & OPTEE_MSG_ATTR_TYPE_MASK) + != OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT) + { + arg->ret = TEE_ERROR_BAD_PARAMETERS; + return; + } + + if (clock_gettime(CLOCK_REALTIME, &ts) < 0) + { + /* Should not happen unless the RTC driver is missing */ + + arg->ret = TEE_ERROR_GENERIC; + return; + } + + arg->params[0].u.value.a = (uint32_t)ts.tv_sec; /* Seconds since epoch. */ + arg->params[0].u.value.b = (uint32_t)ts.tv_nsec; /* Nanoseconds. */ + + arg->ret = TEE_SUCCESS; +} + +/**************************************************************************** + * Name: optee_rpc_cmd_suspend + * + * Description: + * Request from OP-TEE to suspend the current nuttx process. + * + * Parameters: + * arg - Pointer to the RPC message argument, located in a shared page, by + * the secure world, containing the time in msec to sleep. + * + * Returned Value: + * None. Result codes are written into arg->ret. + * + ****************************************************************************/ + +static void optee_rpc_cmd_suspend(FAR struct optee_msg_arg *arg) +{ + useconds_t usec_to_wait; + + /* OP-TEE parameter validation. */ + + if (arg->num_params != 1 || + (arg->params[0].attr & OPTEE_MSG_ATTR_TYPE_MASK) != + OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) + { + arg->ret = TEE_ERROR_BAD_PARAMETERS; + return; + } + + usec_to_wait = arg->params[0].u.value.a * 1000; + + if (usec_to_wait) + { + int ret = nxsig_usleep(usec_to_wait); + + if (ret < 0 && ret != EINTR) + { + arg->ret = TEE_ERROR_GENERIC; + return; + } + } + + arg->ret = TEE_SUCCESS; +} + +/**************************************************************************** + * Name: optee_rpc_cmd_shm_alloc + * + * Description: + * Handle OP-TEE's RPC to allocate shared memory. + * + * Parameters: + * priv - Pointer to the driver's optee_priv_data struct. + * arg - Pointer to the RPC message argument, located in a shared page + * by the secure world. A copy of this message might be sent to the + * supplicant process that runs in userspace for further processing. + * last_page_list - Passes by reference a pointer that will be updated with + * the virtual address of the page list. + * + * Returned Value: + * None. Result codes are written into arg->ret. + * Information about the shared memory is passed through arg->params + * + ****************************************************************************/ + +static void optee_rpc_cmd_shm_alloc(FAR struct optee_priv_data *priv, + FAR struct optee_msg_arg *arg, + FAR void **last_page_list) +{ + FAR struct optee_shm *shm; + size_t n; + size_t size; + int32_t ret = -ENOTTY; + + arg->ret_origin = TEE_ORIGIN_COMMS; + + /* OP-TEE parameter validation. */ + + if (arg->num_params != 1 || + arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) + { + arg->ret = TEE_ERROR_BAD_PARAMETERS; + return; + } + + for (n = 1; n < arg->num_params; n++) + { + if (arg->params[n].attr != OPTEE_MSG_ATTR_TYPE_NONE) + { + arg->ret = TEE_ERROR_BAD_PARAMETERS; + return; + } + } + + size = arg->params[0].u.value.b; + switch (arg->params[0].u.value.a) + { + case OPTEE_MSG_RPC_SHM_TYPE_APPL: +#ifdef CONFIG_DEV_OPTEE_SUPPLICANT + ret = optee_supplicant_cmd_alloc(priv, size, &shm); +#else + arg->ret = TEE_ERROR_NOT_SUPPORTED; + return; +#endif + break; + case OPTEE_MSG_RPC_SHM_TYPE_KERNEL: + ret = optee_shm_alloc(priv, NULL , size, TEE_SHM_ALLOC, &shm); Review Comment: remove space after NULL ########## drivers/misc/optee_supplicant.c: ########## @@ -0,0 +1,608 @@ +/**************************************************************************** + * drivers/misc/optee_supplicant.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/mutex.h> +#include <nuttx/semaphore.h> +#include <nuttx/kmalloc.h> +#include <nuttx/queue.h> +#include <nuttx/idr.h> +#include <string.h> + +#include "optee.h" +#include "optee_supplicant.h" +#include "optee_msg.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Request structure for RPCs serviced by the supplicant. */ + +struct optee_supplicant_req +{ + sq_entry_t link; + uint32_t func; + uint32_t ret; + uint32_t num_params; + FAR struct tee_ioctl_param *params; + sem_t c; +}; + +struct optee_supplicant +{ + mutex_t mutex; + int req_id; + struct sq_queue_s reqs; + FAR struct idr_s *idr; + FAR struct idr_s *shm_idr; + sem_t reqs_c; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct optee_supplicant g_optee_supp; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pop_entry + * + * Description: + * Pop the first request from the request queue, and create unique id. + * + * Parameters: + * num_params - Number of parameters passed. + * id - Pointer to the unique request id. + * + * Returned Value: + * A pointer to the request on success or NULL. + * + ****************************************************************************/ + +static FAR struct optee_supplicant_req * pop_entry(uint32_t num_params, + FAR int *id) +{ + FAR struct optee_supplicant_req *req; + + if (g_optee_supp.req_id != -1) + { + /* Mixing sync/async not supported */ + + return NULL; + } + + if (sq_empty(&g_optee_supp.reqs)) + { + return NULL; + } + + req = (struct optee_supplicant_req *)sq_remfirst(&g_optee_supp.reqs); + + /* The request can't fit in the supplicant's supplied parameter buffer. */ + + if (num_params < req->num_params) + { + return NULL; + } + + *id = idr_alloc(g_optee_supp.idr, req, 0, INT32_MAX); + if (*id < 0) + { + return NULL; + } + + return req; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: optee_supplicant_init + * + * Description: + * Initialize supplicant data. + * + * Parameters: + * shm_idr - A pointer, passed by reference, to the optee driver's shm_idr. + * The destruction of the shm_idr will be handled by + * optee_close(), so we only need to initialize it in this + * context. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void optee_supplicant_init(FAR struct idr_s **shm_idr) +{ + memset(&g_optee_supp, 0, sizeof(g_optee_supp)); + nxmutex_init(&g_optee_supp.mutex); + nxsem_init(&g_optee_supp.reqs_c, 0, 0); + sq_init(&g_optee_supp.reqs); + g_optee_supp.idr = idr_init(); + g_optee_supp.shm_idr = idr_init(); Review Comment: remove shm_idr field, since we can get from filep now ########## drivers/misc/optee_supplicant.h: ########## @@ -0,0 +1,71 @@ +/**************************************************************************** + * drivers/misc/optee_supplicant.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __DRIVERS_MISC_OPTEE_SUPPLICANT_H +#define __DRIVERS_MISC_OPTEE_SUPPLICANT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <sys/types.h> +#include "optee.h" + +/**************************************************************************** + * Public Functions Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +void optee_supplicant_init(FAR struct idr_s **shm_idr); +void optee_supplicant_uninit(void); + +FAR struct optee_shm *optee_supplicant_search_shm(uint32_t id); + +uint32_t optee_supplicant_request(uint32_t func, uint32_t num_params, Review Comment: remove the prototype ########## drivers/misc/optee_rpc.c: ########## @@ -0,0 +1,362 @@ +/**************************************************************************** + * drivers/misc/optee_rpc.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/signal.h> +#include <nuttx/kmalloc.h> +#include <stdint.h> + +#include "optee.h" +#include "optee_msg.h" +#include "optee_rpc.h" + +#ifdef CONFIG_DEV_OPTEE_SUPPLICANT +# include "optee_supplicant.h" +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: optee_rpc_cmd_get_time + * + * Description: + * Return REE wall-clock time (seconds + nanoseconds) to secure world. + * + * Parameters: + * arg - Pointer to the RPC message argument located in shared memory by + * the secure world. The answer will be placed in the same argument. + * + * Returned Value: + * The time is written to: + * arg->params[0].u.value.a containing seconds since epoch + * arg->params[0].u.value.b containing nanoseconds + * Result code is written to arg->ret. + * + ****************************************************************************/ + +static void optee_rpc_cmd_get_time(FAR struct optee_msg_arg *arg) +{ + struct timespec ts; + + /* OP-TEE parameter validation. */ + + if (arg->num_params != 1 || + (arg->params[0].attr & OPTEE_MSG_ATTR_TYPE_MASK) + != OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT) + { + arg->ret = TEE_ERROR_BAD_PARAMETERS; + return; + } + + if (clock_gettime(CLOCK_REALTIME, &ts) < 0) + { + /* Should not happen unless the RTC driver is missing */ + + arg->ret = TEE_ERROR_GENERIC; + return; + } + + arg->params[0].u.value.a = (uint32_t)ts.tv_sec; /* Seconds since epoch. */ + arg->params[0].u.value.b = (uint32_t)ts.tv_nsec; /* Nanoseconds. */ + + arg->ret = TEE_SUCCESS; +} + +/**************************************************************************** + * Name: optee_rpc_cmd_suspend + * + * Description: + * Request from OP-TEE to suspend the current nuttx process. + * + * Parameters: + * arg - Pointer to the RPC message argument, located in a shared page, by + * the secure world, containing the time in msec to sleep. + * + * Returned Value: + * None. Result codes are written into arg->ret. + * + ****************************************************************************/ + +static void optee_rpc_cmd_suspend(FAR struct optee_msg_arg *arg) +{ + useconds_t usec_to_wait; + + /* OP-TEE parameter validation. */ + + if (arg->num_params != 1 || + (arg->params[0].attr & OPTEE_MSG_ATTR_TYPE_MASK) != + OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) + { + arg->ret = TEE_ERROR_BAD_PARAMETERS; + return; + } + + usec_to_wait = arg->params[0].u.value.a * 1000; + + if (usec_to_wait) + { + int ret = nxsig_usleep(usec_to_wait); + + if (ret < 0 && ret != EINTR) + { + arg->ret = TEE_ERROR_GENERIC; + return; + } + } + + arg->ret = TEE_SUCCESS; +} + +/**************************************************************************** + * Name: optee_rpc_cmd_shm_alloc + * + * Description: + * Handle OP-TEE's RPC to allocate shared memory. + * + * Parameters: + * priv - Pointer to the driver's optee_priv_data struct. + * arg - Pointer to the RPC message argument, located in a shared page + * by the secure world. A copy of this message might be sent to the + * supplicant process that runs in userspace for further processing. + * last_page_list - Passes by reference a pointer that will be updated with + * the virtual address of the page list. + * + * Returned Value: + * None. Result codes are written into arg->ret. + * Information about the shared memory is passed through arg->params + * + ****************************************************************************/ + +static void optee_rpc_cmd_shm_alloc(FAR struct optee_priv_data *priv, + FAR struct optee_msg_arg *arg, + FAR void **last_page_list) +{ + FAR struct optee_shm *shm; + size_t n; + size_t size; + int32_t ret = -ENOTTY; + + arg->ret_origin = TEE_ORIGIN_COMMS; + + /* OP-TEE parameter validation. */ + + if (arg->num_params != 1 || + arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) + { + arg->ret = TEE_ERROR_BAD_PARAMETERS; + return; + } + + for (n = 1; n < arg->num_params; n++) + { + if (arg->params[n].attr != OPTEE_MSG_ATTR_TYPE_NONE) + { + arg->ret = TEE_ERROR_BAD_PARAMETERS; + return; + } + } + + size = arg->params[0].u.value.b; + switch (arg->params[0].u.value.a) + { + case OPTEE_MSG_RPC_SHM_TYPE_APPL: +#ifdef CONFIG_DEV_OPTEE_SUPPLICANT + ret = optee_supplicant_cmd_alloc(priv, size, &shm); +#else + arg->ret = TEE_ERROR_NOT_SUPPORTED; + return; +#endif + break; Review Comment: move before line 189 ########## drivers/misc/optee_supplicant.c: ########## @@ -0,0 +1,608 @@ +/**************************************************************************** + * drivers/misc/optee_supplicant.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/mutex.h> +#include <nuttx/semaphore.h> +#include <nuttx/kmalloc.h> +#include <nuttx/queue.h> +#include <nuttx/idr.h> +#include <string.h> + +#include "optee.h" +#include "optee_supplicant.h" +#include "optee_msg.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Request structure for RPCs serviced by the supplicant. */ + +struct optee_supplicant_req +{ + sq_entry_t link; + uint32_t func; + uint32_t ret; + uint32_t num_params; + FAR struct tee_ioctl_param *params; + sem_t c; +}; + +struct optee_supplicant +{ + mutex_t mutex; + int req_id; + struct sq_queue_s reqs; + FAR struct idr_s *idr; + FAR struct idr_s *shm_idr; + sem_t reqs_c; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct optee_supplicant g_optee_supp; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pop_entry + * + * Description: + * Pop the first request from the request queue, and create unique id. + * + * Parameters: + * num_params - Number of parameters passed. + * id - Pointer to the unique request id. + * + * Returned Value: + * A pointer to the request on success or NULL. + * + ****************************************************************************/ + +static FAR struct optee_supplicant_req * pop_entry(uint32_t num_params, + FAR int *id) +{ + FAR struct optee_supplicant_req *req; + + if (g_optee_supp.req_id != -1) + { + /* Mixing sync/async not supported */ + + return NULL; + } + + if (sq_empty(&g_optee_supp.reqs)) + { + return NULL; + } + + req = (struct optee_supplicant_req *)sq_remfirst(&g_optee_supp.reqs); + + /* The request can't fit in the supplicant's supplied parameter buffer. */ + + if (num_params < req->num_params) + { + return NULL; + } + + *id = idr_alloc(g_optee_supp.idr, req, 0, INT32_MAX); + if (*id < 0) + { + return NULL; + } + + return req; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: optee_supplicant_init + * + * Description: + * Initialize supplicant data. + * + * Parameters: + * shm_idr - A pointer, passed by reference, to the optee driver's shm_idr. + * The destruction of the shm_idr will be handled by + * optee_close(), so we only need to initialize it in this + * context. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void optee_supplicant_init(FAR struct idr_s **shm_idr) Review Comment: let's allocate and return optee_supplicant to caller for register_driver ########## drivers/misc/optee_supplicant.c: ########## @@ -0,0 +1,608 @@ +/**************************************************************************** + * drivers/misc/optee_supplicant.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/mutex.h> +#include <nuttx/semaphore.h> +#include <nuttx/kmalloc.h> +#include <nuttx/queue.h> +#include <nuttx/idr.h> +#include <string.h> + +#include "optee.h" +#include "optee_supplicant.h" +#include "optee_msg.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Request structure for RPCs serviced by the supplicant. */ + +struct optee_supplicant_req +{ + sq_entry_t link; + uint32_t func; + uint32_t ret; + uint32_t num_params; + FAR struct tee_ioctl_param *params; + sem_t c; +}; + +struct optee_supplicant +{ + mutex_t mutex; + int req_id; + struct sq_queue_s reqs; + FAR struct idr_s *idr; + FAR struct idr_s *shm_idr; + sem_t reqs_c; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct optee_supplicant g_optee_supp; Review Comment: let's allocate and attach g_optee_supp to inode::i_private when register `/dev/teepriv`, we can: 1. check whether inode::i_private is NULL to know CA/SUPPLICANT 2. restore optee_supplicant from f_inode->i_private ########## drivers/misc/optee_supplicant.c: ########## @@ -0,0 +1,608 @@ +/**************************************************************************** + * drivers/misc/optee_supplicant.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/mutex.h> +#include <nuttx/semaphore.h> +#include <nuttx/kmalloc.h> +#include <nuttx/queue.h> +#include <nuttx/idr.h> +#include <string.h> + +#include "optee.h" +#include "optee_supplicant.h" +#include "optee_msg.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Request structure for RPCs serviced by the supplicant. */ + +struct optee_supplicant_req +{ + sq_entry_t link; + uint32_t func; + uint32_t ret; + uint32_t num_params; + FAR struct tee_ioctl_param *params; + sem_t c; +}; + +struct optee_supplicant +{ + mutex_t mutex; + int req_id; + struct sq_queue_s reqs; + FAR struct idr_s *idr; + FAR struct idr_s *shm_idr; + sem_t reqs_c; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct optee_supplicant g_optee_supp; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pop_entry + * + * Description: + * Pop the first request from the request queue, and create unique id. + * + * Parameters: + * num_params - Number of parameters passed. + * id - Pointer to the unique request id. + * + * Returned Value: + * A pointer to the request on success or NULL. + * + ****************************************************************************/ + +static FAR struct optee_supplicant_req * pop_entry(uint32_t num_params, + FAR int *id) +{ + FAR struct optee_supplicant_req *req; + + if (g_optee_supp.req_id != -1) + { + /* Mixing sync/async not supported */ + + return NULL; + } + + if (sq_empty(&g_optee_supp.reqs)) + { + return NULL; + } + + req = (struct optee_supplicant_req *)sq_remfirst(&g_optee_supp.reqs); + + /* The request can't fit in the supplicant's supplied parameter buffer. */ + + if (num_params < req->num_params) + { + return NULL; + } + + *id = idr_alloc(g_optee_supp.idr, req, 0, INT32_MAX); + if (*id < 0) + { + return NULL; + } + + return req; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: optee_supplicant_init + * + * Description: + * Initialize supplicant data. + * + * Parameters: + * shm_idr - A pointer, passed by reference, to the optee driver's shm_idr. + * The destruction of the shm_idr will be handled by + * optee_close(), so we only need to initialize it in this + * context. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void optee_supplicant_init(FAR struct idr_s **shm_idr) +{ + memset(&g_optee_supp, 0, sizeof(g_optee_supp)); + nxmutex_init(&g_optee_supp.mutex); + nxsem_init(&g_optee_supp.reqs_c, 0, 0); + sq_init(&g_optee_supp.reqs); + g_optee_supp.idr = idr_init(); + g_optee_supp.shm_idr = idr_init(); + *shm_idr = g_optee_supp.shm_idr; + g_optee_supp.req_id = -1; +} + +/**************************************************************************** + * Name: optee_supplicant_uninit + * + * Description: + * Uninitialize supplicant data. + * + * Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void optee_supplicant_uninit(void) Review Comment: don't need ########## drivers/misc/optee_supplicant.c: ########## @@ -0,0 +1,608 @@ +/**************************************************************************** + * drivers/misc/optee_supplicant.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/mutex.h> +#include <nuttx/semaphore.h> +#include <nuttx/kmalloc.h> +#include <nuttx/queue.h> +#include <nuttx/idr.h> +#include <string.h> + +#include "optee.h" +#include "optee_supplicant.h" +#include "optee_msg.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Request structure for RPCs serviced by the supplicant. */ + +struct optee_supplicant_req +{ + sq_entry_t link; + uint32_t func; + uint32_t ret; + uint32_t num_params; + FAR struct tee_ioctl_param *params; + sem_t c; +}; + +struct optee_supplicant +{ + mutex_t mutex; + int req_id; + struct sq_queue_s reqs; + FAR struct idr_s *idr; + FAR struct idr_s *shm_idr; + sem_t reqs_c; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct optee_supplicant g_optee_supp; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pop_entry + * + * Description: + * Pop the first request from the request queue, and create unique id. + * + * Parameters: + * num_params - Number of parameters passed. + * id - Pointer to the unique request id. + * + * Returned Value: + * A pointer to the request on success or NULL. + * + ****************************************************************************/ + +static FAR struct optee_supplicant_req * pop_entry(uint32_t num_params, Review Comment: remove space after `*` ########## drivers/misc/optee_rpc.c: ########## @@ -0,0 +1,362 @@ +/**************************************************************************** + * drivers/misc/optee_rpc.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/signal.h> +#include <nuttx/kmalloc.h> +#include <stdint.h> + +#include "optee.h" +#include "optee_msg.h" +#include "optee_rpc.h" + +#ifdef CONFIG_DEV_OPTEE_SUPPLICANT +# include "optee_supplicant.h" +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: optee_rpc_cmd_get_time + * + * Description: + * Return REE wall-clock time (seconds + nanoseconds) to secure world. + * + * Parameters: + * arg - Pointer to the RPC message argument located in shared memory by + * the secure world. The answer will be placed in the same argument. + * + * Returned Value: + * The time is written to: + * arg->params[0].u.value.a containing seconds since epoch + * arg->params[0].u.value.b containing nanoseconds + * Result code is written to arg->ret. + * + ****************************************************************************/ + +static void optee_rpc_cmd_get_time(FAR struct optee_msg_arg *arg) +{ + struct timespec ts; + + /* OP-TEE parameter validation. */ + + if (arg->num_params != 1 || + (arg->params[0].attr & OPTEE_MSG_ATTR_TYPE_MASK) + != OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT) + { + arg->ret = TEE_ERROR_BAD_PARAMETERS; + return; + } + + if (clock_gettime(CLOCK_REALTIME, &ts) < 0) + { + /* Should not happen unless the RTC driver is missing */ + + arg->ret = TEE_ERROR_GENERIC; + return; + } + + arg->params[0].u.value.a = (uint32_t)ts.tv_sec; /* Seconds since epoch. */ + arg->params[0].u.value.b = (uint32_t)ts.tv_nsec; /* Nanoseconds. */ + + arg->ret = TEE_SUCCESS; +} + +/**************************************************************************** + * Name: optee_rpc_cmd_suspend + * + * Description: + * Request from OP-TEE to suspend the current nuttx process. + * + * Parameters: + * arg - Pointer to the RPC message argument, located in a shared page, by + * the secure world, containing the time in msec to sleep. + * + * Returned Value: + * None. Result codes are written into arg->ret. + * + ****************************************************************************/ + +static void optee_rpc_cmd_suspend(FAR struct optee_msg_arg *arg) +{ + useconds_t usec_to_wait; + + /* OP-TEE parameter validation. */ + + if (arg->num_params != 1 || + (arg->params[0].attr & OPTEE_MSG_ATTR_TYPE_MASK) != + OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) + { + arg->ret = TEE_ERROR_BAD_PARAMETERS; + return; + } + + usec_to_wait = arg->params[0].u.value.a * 1000; + + if (usec_to_wait) + { + int ret = nxsig_usleep(usec_to_wait); + + if (ret < 0 && ret != EINTR) + { + arg->ret = TEE_ERROR_GENERIC; + return; + } + } + + arg->ret = TEE_SUCCESS; +} + +/**************************************************************************** + * Name: optee_rpc_cmd_shm_alloc + * + * Description: + * Handle OP-TEE's RPC to allocate shared memory. + * + * Parameters: + * priv - Pointer to the driver's optee_priv_data struct. + * arg - Pointer to the RPC message argument, located in a shared page + * by the secure world. A copy of this message might be sent to the + * supplicant process that runs in userspace for further processing. + * last_page_list - Passes by reference a pointer that will be updated with + * the virtual address of the page list. + * + * Returned Value: + * None. Result codes are written into arg->ret. + * Information about the shared memory is passed through arg->params + * + ****************************************************************************/ + +static void optee_rpc_cmd_shm_alloc(FAR struct optee_priv_data *priv, + FAR struct optee_msg_arg *arg, + FAR void **last_page_list) +{ + FAR struct optee_shm *shm; + size_t n; + size_t size; + int32_t ret = -ENOTTY; + + arg->ret_origin = TEE_ORIGIN_COMMS; + + /* OP-TEE parameter validation. */ + + if (arg->num_params != 1 || + arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) + { + arg->ret = TEE_ERROR_BAD_PARAMETERS; + return; + } + + for (n = 1; n < arg->num_params; n++) + { + if (arg->params[n].attr != OPTEE_MSG_ATTR_TYPE_NONE) + { + arg->ret = TEE_ERROR_BAD_PARAMETERS; + return; + } + } + + size = arg->params[0].u.value.b; + switch (arg->params[0].u.value.a) + { + case OPTEE_MSG_RPC_SHM_TYPE_APPL: +#ifdef CONFIG_DEV_OPTEE_SUPPLICANT + ret = optee_supplicant_cmd_alloc(priv, size, &shm); +#else + arg->ret = TEE_ERROR_NOT_SUPPORTED; + return; +#endif + break; + case OPTEE_MSG_RPC_SHM_TYPE_KERNEL: + ret = optee_shm_alloc(priv, NULL , size, TEE_SHM_ALLOC, &shm); + break; + default: + ret = -EINVAL; Review Comment: merge to line 161 and remove default block -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org