OP-TEE: update optee_linuxdriver to match updated optee_os & optee_client
Match the optee_os version 1.5 or later. Main update features: 1.Support 32-bit client working with 64-bit linux kernel. 2.Fix Shared Memory protection. 3.Add mutex to serialize tee-supplicant request. 4.Revert "rename tee-supplicant to tee_supplicant". cherry-pick from 3.10 commit id:5f6467dc09e8c00f7fa6a621b3aad7046ae84d48 Change-Id: I5c77ed85aa56e36d346be7c4462c5a15120df439 Signed-off-by: sean.huang <sean.huang@rock-chips.com>
This commit is contained in:
parent
17f6cd3459
commit
f7b87e8de9
15 changed files with 178 additions and 74 deletions
|
|
@ -173,6 +173,8 @@ source security/tomoyo/Kconfig
|
|||
source security/apparmor/Kconfig
|
||||
source security/yama/Kconfig
|
||||
|
||||
source security/optee_linuxdriver/Kconfig
|
||||
|
||||
source security/integrity/Kconfig
|
||||
|
||||
choice
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/
|
|||
obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/
|
||||
obj-$(CONFIG_SECURITY_YAMA) += yama/
|
||||
obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
|
||||
obj-$(CONFIG_TEE_SUPPORT) += optee_linuxdriver/
|
||||
|
||||
# Object integrity file lists
|
||||
subdir-$(CONFIG_INTEGRITY) += integrity
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
# Trursted Execution Environment Configuration
|
||||
config TEE_SUPPORT
|
||||
bool "Trusted Execution Environment Support"
|
||||
default y
|
||||
default n
|
||||
---help---
|
||||
This implements the Trusted Execution Environment (TEE) Client
|
||||
API Specification from GlobalPlatform Device Technology.
|
||||
|
|
|
|||
|
|
@ -32,11 +32,17 @@
|
|||
#include <arm_common/teesmc.h>
|
||||
#include <arm_common/teesmc_st.h>
|
||||
|
||||
#include <linux/cpumask.h>
|
||||
|
||||
#include "tee_mem.h"
|
||||
#include "tee_tz_op.h"
|
||||
#include "tee_tz_priv.h"
|
||||
#include "handle.h"
|
||||
|
||||
#ifdef CONFIG_OUTER_CACHE
|
||||
#undef CONFIG_OUTER_CACHE
|
||||
#endif
|
||||
|
||||
#define SWITCH_CPU0_DEBUG
|
||||
|
||||
#define _TEE_TZ_NAME "armtz"
|
||||
|
|
@ -71,9 +77,9 @@ static struct handle_db shm_handle_db = HANDLE_DB_INITIALIZER;
|
|||
static void switch_cpumask_to_cpu0(cpumask_t *saved_cpu_mask)
|
||||
{
|
||||
long ret;
|
||||
|
||||
cpumask_t local_cpu_mask = CPU_MASK_NONE;
|
||||
pr_info("switch_cpumask_to_cpu cpu0\n");
|
||||
cpu_set(0, local_cpu_mask);
|
||||
cpumask_set_cpu(0, &local_cpu_mask);
|
||||
cpumask_copy(saved_cpu_mask, tsk_cpus_allowed(current));
|
||||
ret = sched_setaffinity(0, &local_cpu_mask);
|
||||
if (ret)
|
||||
|
|
@ -83,7 +89,7 @@ static void switch_cpumask_to_cpu0(cpumask_t *saved_cpu_mask)
|
|||
static void restore_cpumask(cpumask_t *saved_cpu_mask)
|
||||
{
|
||||
long ret;
|
||||
pr_info("restore_cpumask cpu0\n");
|
||||
|
||||
ret = sched_setaffinity(0, saved_cpu_mask);
|
||||
if (ret)
|
||||
pr_err("sched_setaffinity #2 -> 0x%lX", ret);
|
||||
|
|
@ -451,9 +457,9 @@ static void call_tee(struct tee_tz *ptee,
|
|||
#endif
|
||||
ret = param.a0;
|
||||
|
||||
if (ret == TEESMC_RETURN_EBUSY) {
|
||||
if (ret == TEESMC_RETURN_ETHREAD_LIMIT) {
|
||||
/*
|
||||
* Since secure world returned busy, release the
|
||||
* Since secure world is out of threads, release the
|
||||
* lock we had when entering this function and wait
|
||||
* for "something to happen" (something else to
|
||||
* exit from secure world and needed resources may
|
||||
|
|
|
|||
|
|
@ -173,10 +173,8 @@ static void _tee_context_do_release(struct kref *kref)
|
|||
|
||||
dev_dbg(_DEV(tee), "%s: > ctx=%p\n", __func__, ctx);
|
||||
|
||||
mutex_lock(&tee->lock);
|
||||
tee_dec_stats(&tee->stats[TEE_STATS_CONTEXT_IDX]);
|
||||
list_del(&ctx->entry);
|
||||
mutex_unlock(&tee->lock);
|
||||
|
||||
devm_kfree(_DEV(tee), ctx);
|
||||
tee_put(tee);
|
||||
|
|
@ -202,10 +200,8 @@ static int is_in_list(struct tee *tee, struct list_head *entry)
|
|||
{
|
||||
int present = 1;
|
||||
|
||||
mutex_lock(&tee->lock);
|
||||
if ((entry->next == LIST_POISON1) && (entry->prev == LIST_POISON2))
|
||||
present = 0;
|
||||
mutex_unlock(&tee->lock);
|
||||
return present;
|
||||
}
|
||||
|
||||
|
|
@ -245,7 +241,9 @@ void tee_context_destroy(struct tee_context *ctx)
|
|||
|
||||
dev_dbg(_DEV(tee), "%s: ctx=%p\n", __func__, ctx);
|
||||
|
||||
mutex_lock(&tee->lock);
|
||||
tee_context_put(ctx);
|
||||
mutex_unlock(&tee->lock);
|
||||
}
|
||||
|
||||
int tee_context_copy_from_client(const struct tee_context *ctx,
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
#define _TEE_CORE_FW_VER "1:0.1"
|
||||
|
||||
static char *_tee_supp_app_name = "tee_supplicant";
|
||||
static char *_tee_supp_app_name = "tee-supplicant";
|
||||
|
||||
/* Store the class misc reference */
|
||||
static struct class *misc_class;
|
||||
|
|
@ -368,24 +368,33 @@ static long tee_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
{
|
||||
int ret = -EINVAL;
|
||||
struct tee_context *ctx = filp->private_data;
|
||||
void __user *u_arg;
|
||||
|
||||
BUG_ON(!ctx);
|
||||
BUG_ON(!ctx->tee);
|
||||
|
||||
dev_dbg(_DEV(ctx->tee), "%s: > cmd nr=%d\n", __func__, _IOC_NR(cmd));
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
if (is_compat_task())
|
||||
u_arg = compat_ptr(arg);
|
||||
else
|
||||
u_arg = (void __user *)arg;
|
||||
#else
|
||||
u_arg = (void __user *)arg;
|
||||
#endif
|
||||
|
||||
switch (cmd) {
|
||||
case TEE_OPEN_SESSION_IOC:
|
||||
ret =
|
||||
tee_do_create_session(ctx, (struct tee_cmd_io __user *)arg);
|
||||
ret = tee_do_create_session(ctx,
|
||||
(struct tee_cmd_io __user *)u_arg);
|
||||
break;
|
||||
case TEE_ALLOC_SHM_IOC:
|
||||
ret = tee_do_shm_alloc(ctx, (struct tee_shm_io __user *)arg);
|
||||
ret = tee_do_shm_alloc(ctx, (struct tee_shm_io __user *)u_arg);
|
||||
break;
|
||||
case TEE_GET_FD_FOR_RPC_SHM_IOC:
|
||||
ret =
|
||||
tee_do_get_fd_for_rpc_shm(ctx,
|
||||
(struct tee_shm_io __user *)arg);
|
||||
ret = tee_do_get_fd_for_rpc_shm(ctx,
|
||||
(struct tee_shm_io __user *)u_arg);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
|
|
@ -403,8 +412,10 @@ static const struct file_operations tee_file_fops = {
|
|||
.write = tee_supp_write,
|
||||
.open = tee_ctx_open,
|
||||
.release = tee_ctx_release,
|
||||
.unlocked_ioctl = tee_ioctl,
|
||||
.compat_ioctl = tee_ioctl
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = tee_ioctl,
|
||||
#endif
|
||||
.unlocked_ioctl = tee_ioctl
|
||||
};
|
||||
|
||||
static void tee_plt_device_release(struct device *dev)
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
static void reset_tee_cmd(struct tee_cmd_io *cmd)
|
||||
{
|
||||
memset(cmd, 0, sizeof(struct tee_cmd_io));
|
||||
cmd->fd_sess = -1;
|
||||
cmd->cmd = 0;
|
||||
cmd->uuid = NULL;
|
||||
|
|
@ -230,7 +231,7 @@ TEEC_Result TEEC_AllocateSharedMemory(TEEC_Context *context,
|
|||
shm = (struct tee_shm *)(long)shm_io.fd_shm;
|
||||
shared_memory->buffer = shm->kaddr;
|
||||
|
||||
pr_debug("%s(%zd) => fd=%d, kaddr=%p\n", __func__,
|
||||
pr_debug("%s(%d) => fd=%d, kaddr=%p\n", __func__,
|
||||
shm_io.size, shm_io.fd_shm, (void *)shared_memory->buffer);
|
||||
|
||||
return TEEC_SUCCESS;
|
||||
|
|
|
|||
|
|
@ -359,6 +359,9 @@ static int tee_session_release(struct inode *inode, struct file *filp)
|
|||
|
||||
const struct file_operations tee_session_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = tee_session_ioctl,
|
||||
#endif
|
||||
.unlocked_ioctl = tee_session_ioctl,
|
||||
.compat_ioctl = tee_session_ioctl,
|
||||
.release = tee_session_release,
|
||||
|
|
@ -383,14 +386,14 @@ int tee_session_close_and_destroy(struct tee_session *sess)
|
|||
|
||||
ret = tee_session_close_be(sess);
|
||||
|
||||
mutex_lock(&sess->ctx->tee->lock);
|
||||
mutex_lock(&tee->lock);
|
||||
tee_dec_stats(&tee->stats[TEE_STATS_SESSION_IDX]);
|
||||
list_del(&sess->entry);
|
||||
mutex_unlock(&sess->ctx->tee->lock);
|
||||
|
||||
devm_kfree(_DEV(tee), sess);
|
||||
tee_context_put(ctx);
|
||||
tee_put(tee);
|
||||
mutex_unlock(&tee->lock);
|
||||
|
||||
dev_dbg(_DEV(tee), "%s: <\n", __func__);
|
||||
return ret;
|
||||
|
|
@ -424,6 +427,7 @@ struct tee_session *tee_session_create_and_open(struct tee_context *ctx,
|
|||
sess->ctx = ctx;
|
||||
|
||||
ret = tee_session_open_be(sess, cmd_io);
|
||||
mutex_lock(&tee->lock);
|
||||
if (ret || !sess->sessid || cmd_io->err) {
|
||||
dev_err(_DEV(tee), "%s: ERROR ret=%d (err=0x%08x, org=%d, sessid=0x%08x)\n",
|
||||
__func__, ret, cmd_io->err,
|
||||
|
|
@ -431,13 +435,13 @@ struct tee_session *tee_session_create_and_open(struct tee_context *ctx,
|
|||
tee_put(tee);
|
||||
tee_context_put(ctx);
|
||||
devm_kfree(_DEV(tee), sess);
|
||||
mutex_unlock(&tee->lock);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mutex_lock(&tee->lock);
|
||||
tee_inc_stats(&tee->stats[TEE_STATS_SESSION_IDX]);
|
||||
list_add_tail(&sess->entry, &ctx->list_sess);
|
||||
mutex_unlock(&tee->lock);
|
||||
|
|
@ -728,8 +732,7 @@ static void _update_client_tee_cmd(struct tee_session *sess,
|
|||
dev_dbg(_DEV_TEE,
|
||||
"Size has been updated by the TA %zd != %zd\n",
|
||||
size_new,
|
||||
cmd_io->op->params[idx].tmpref.
|
||||
size);
|
||||
cmd_io->op->params[idx].tmpref.size);
|
||||
tee_put_user(ctx, size_new,
|
||||
&cmd_io->op->params[idx].tmpref.size);
|
||||
}
|
||||
|
|
@ -742,8 +745,7 @@ static void _update_client_tee_cmd(struct tee_session *sess,
|
|||
dev_err(_DEV_TEE,
|
||||
" *** Wrong returned size from %d:%zd > %zd\n",
|
||||
idx, size_new,
|
||||
cmd_io->op->params[idx].tmpref.
|
||||
size);
|
||||
cmd_io->op->params[idx].tmpref.size);
|
||||
|
||||
else if (tee_copy_to_user
|
||||
(ctx,
|
||||
|
|
@ -758,6 +760,7 @@ static void _update_client_tee_cmd(struct tee_session *sess,
|
|||
case TEEC_MEMREF_PARTIAL_OUTPUT:
|
||||
case TEEC_MEMREF_PARTIAL_INOUT:
|
||||
case TEEC_MEMREF_WHOLE:
|
||||
parent = &cmd->param.c_shm[idx];
|
||||
if (type == TEEC_MEMREF_WHOLE) {
|
||||
offset = 0;
|
||||
size = parent->size;
|
||||
|
|
@ -765,7 +768,6 @@ static void _update_client_tee_cmd(struct tee_session *sess,
|
|||
offset = cmd_io->op->params[idx].memref.offset;
|
||||
size = cmd_io->op->params[idx].memref.size;
|
||||
}
|
||||
parent = &cmd->param.c_shm[idx];
|
||||
|
||||
/* Returned updated size */
|
||||
size_new = cmd->param.params[idx].shm->size_req;
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ struct tee_shm *tee_shm_alloc_from_rpc(struct tee *tee, size_t size)
|
|||
|
||||
INMSG();
|
||||
|
||||
mutex_lock(&tee->lock);
|
||||
shm = tee_shm_alloc(tee, size, TEE_SHM_TEMP | TEE_SHM_FROM_RPC);
|
||||
if (IS_ERR_OR_NULL(shm)) {
|
||||
dev_err(_DEV(tee), "%s: buffer allocation failed (%ld)\n",
|
||||
|
|
@ -50,30 +51,32 @@ struct tee_shm *tee_shm_alloc_from_rpc(struct tee *tee, size_t size)
|
|||
goto out;
|
||||
}
|
||||
|
||||
mutex_lock(&tee->lock);
|
||||
tee_inc_stats(&tee->stats[TEE_STATS_SHM_IDX]);
|
||||
list_add_tail(&shm->entry, &tee->list_rpc_shm);
|
||||
mutex_unlock(&tee->lock);
|
||||
|
||||
shm->ctx = NULL;
|
||||
|
||||
out:
|
||||
mutex_unlock(&tee->lock);
|
||||
OUTMSGX(shm);
|
||||
return shm;
|
||||
}
|
||||
|
||||
void tee_shm_free_from_rpc(struct tee_shm *shm)
|
||||
{
|
||||
struct tee *tee;
|
||||
|
||||
if (shm == NULL)
|
||||
return;
|
||||
|
||||
tee = shm->tee;
|
||||
mutex_lock(&tee->lock);
|
||||
if (shm->ctx == NULL) {
|
||||
mutex_lock(&shm->tee->lock);
|
||||
tee_dec_stats(&shm->tee->stats[TEE_STATS_SHM_IDX]);
|
||||
list_del(&shm->entry);
|
||||
mutex_unlock(&shm->tee->lock);
|
||||
}
|
||||
|
||||
tee_shm_free(shm);
|
||||
mutex_unlock(&tee->lock);
|
||||
}
|
||||
|
||||
struct tee_shm *tee_shm_alloc(struct tee *tee, size_t size, uint32_t flags)
|
||||
|
|
@ -397,14 +400,14 @@ int tee_shm_alloc_io(struct tee_context *ctx, struct tee_shm_io *shm_io)
|
|||
|
||||
if (ctx->usr_client)
|
||||
shm_io->fd_shm = 0;
|
||||
else
|
||||
shm_io->ptr = NULL;
|
||||
|
||||
mutex_lock(&tee->lock);
|
||||
shm = tee_shm_alloc(tee, shm_io->size, shm_io->flags);
|
||||
if (IS_ERR_OR_NULL(shm)) {
|
||||
dev_err(_DEV(tee), "%s: buffer allocation failed (%ld)\n",
|
||||
__func__, PTR_ERR(shm));
|
||||
return PTR_ERR(shm);
|
||||
ret = PTR_ERR(shm);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ctx->usr_client) {
|
||||
|
|
@ -416,8 +419,7 @@ int tee_shm_alloc_io(struct tee_context *ctx, struct tee_shm_io *shm_io)
|
|||
}
|
||||
|
||||
shm->flags |= TEEC_MEM_DMABUF;
|
||||
} else
|
||||
shm_io->ptr = shm;
|
||||
}
|
||||
|
||||
shm->ctx = ctx;
|
||||
shm->dev = get_device(_DEV(tee));
|
||||
|
|
@ -425,11 +427,10 @@ int tee_shm_alloc_io(struct tee_context *ctx, struct tee_shm_io *shm_io)
|
|||
BUG_ON(ret); /* tee_core_get must not issue */
|
||||
tee_context_get(ctx);
|
||||
|
||||
mutex_lock(&tee->lock);
|
||||
tee_inc_stats(&tee->stats[TEE_STATS_SHM_IDX]);
|
||||
list_add_tail(&shm->entry, &ctx->list_shm);
|
||||
mutex_unlock(&tee->lock);
|
||||
out:
|
||||
mutex_unlock(&tee->lock);
|
||||
OUTMSG(ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -443,13 +444,13 @@ void tee_shm_free_io(struct tee_shm *shm)
|
|||
mutex_lock(&ctx->tee->lock);
|
||||
tee_dec_stats(&tee->stats[TEE_STATS_SHM_IDX]);
|
||||
list_del(&shm->entry);
|
||||
mutex_unlock(&ctx->tee->lock);
|
||||
|
||||
tee_shm_free(shm);
|
||||
tee_put(ctx->tee);
|
||||
tee_context_put(ctx);
|
||||
if (dev)
|
||||
put_device(dev);
|
||||
mutex_unlock(&ctx->tee->lock);
|
||||
}
|
||||
|
||||
/* Buffer allocated by rpc from fw and to be accessed by the user
|
||||
|
|
@ -465,6 +466,7 @@ int tee_shm_fd_for_rpc(struct tee_context *ctx, struct tee_shm_io *shm_io)
|
|||
|
||||
shm_io->fd_shm = 0;
|
||||
|
||||
mutex_lock(&tee->lock);
|
||||
if (!list_empty(&tee->list_rpc_shm)) {
|
||||
list_for_each(pshm, &tee->list_rpc_shm) {
|
||||
shm = list_entry(pshm, struct tee_shm, entry);
|
||||
|
|
@ -485,9 +487,7 @@ found:
|
|||
}
|
||||
|
||||
shm->ctx = ctx;
|
||||
mutex_lock(&tee->lock);
|
||||
list_move(&shm->entry, &ctx->list_shm);
|
||||
mutex_unlock(&tee->lock);
|
||||
|
||||
shm->dev = get_device(_DEV(tee));
|
||||
ret = tee_get(tee);
|
||||
|
|
@ -496,6 +496,7 @@ found:
|
|||
|
||||
BUG_ON(!tee->ops->shm_inc_ref(shm));
|
||||
out:
|
||||
mutex_unlock(&tee->lock);
|
||||
OUTMSG(ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -722,10 +723,12 @@ struct tee_shm *tee_shm_get(struct tee_context *ctx, TEEC_SharedMemory *c_shm,
|
|||
dev_dbg(_DEV(tee), "%s: > fd=%d flags=%08x\n",
|
||||
__func__, c_shm->d.fd, c_shm->flags);
|
||||
|
||||
mutex_lock(&tee->lock);
|
||||
shm = kzalloc(sizeof(*shm), GFP_KERNEL);
|
||||
if (IS_ERR_OR_NULL(shm)) {
|
||||
dev_err(_DEV(tee), "can't alloc tee_shm\n");
|
||||
return ERR_PTR(-ENOMEM);
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
shm->ctx = ctx;
|
||||
|
|
@ -773,11 +776,13 @@ struct tee_shm *tee_shm_get(struct tee_context *ctx, TEEC_SharedMemory *c_shm,
|
|||
#endif
|
||||
}
|
||||
|
||||
mutex_unlock(&tee->lock);
|
||||
OUTMSGX(shm);
|
||||
return shm;
|
||||
|
||||
err:
|
||||
kfree(shm);
|
||||
mutex_unlock(&tee->lock);
|
||||
OUTMSGX(ERR_PTR(ret));
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
|
@ -792,6 +797,7 @@ void tee_shm_put(struct tee_context *ctx, struct tee_shm *shm)
|
|||
BUG_ON(!shm);
|
||||
BUG_ON(!(shm->flags & TEE_SHM_MEMREF));
|
||||
|
||||
mutex_lock(&tee->lock);
|
||||
if (shm->flags & TEEC_MEM_DMABUF) {
|
||||
struct tee_shm_dma_buf *sdb;
|
||||
struct dma_buf *dma_buf;
|
||||
|
|
@ -810,6 +816,7 @@ void tee_shm_put(struct tee_context *ctx, struct tee_shm *shm)
|
|||
}
|
||||
|
||||
kfree(shm);
|
||||
mutex_unlock(&tee->lock);
|
||||
OUTMSG(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -78,10 +78,14 @@ enum teec_rpc_result tee_supp_cmd(struct tee *tee,
|
|||
if (sizeof(rpc->commToUser) < datalen)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Other threads blocks here until we've copied our
|
||||
* answer from the supplicant
|
||||
*/
|
||||
mutex_lock(&rpc->thrd_mutex);
|
||||
|
||||
mutex_lock(&rpc->outsync);
|
||||
|
||||
memcpy(&rpc->commToUser, data, datalen);
|
||||
|
||||
mutex_unlock(&rpc->outsync);
|
||||
|
||||
dev_dbg(tee->dev,
|
||||
|
|
@ -97,11 +101,11 @@ enum teec_rpc_result tee_supp_cmd(struct tee *tee,
|
|||
rpc->commToUser.cmd);
|
||||
|
||||
mutex_lock(&rpc->insync);
|
||||
|
||||
memcpy(data, &rpc->commFromUser, datalen);
|
||||
|
||||
mutex_unlock(&rpc->insync);
|
||||
|
||||
mutex_unlock(&rpc->thrd_mutex);
|
||||
|
||||
res = TEEC_RPC_OK;
|
||||
|
||||
break;
|
||||
|
|
@ -258,6 +262,7 @@ int tee_supp_init(struct tee *tee)
|
|||
__SEMAPHORE_INITIALIZER(rpc->datafromuser, 0);
|
||||
rpc->datatouser = (struct semaphore)
|
||||
__SEMAPHORE_INITIALIZER(rpc->datatouser, 0);
|
||||
mutex_init(&rpc->thrd_mutex);
|
||||
mutex_init(&rpc->outsync);
|
||||
mutex_init(&rpc->insync);
|
||||
atomic_set(&rpc->used, 0);
|
||||
|
|
|
|||
|
|
@ -65,16 +65,21 @@ struct tee_rpc_free {
|
|||
};
|
||||
|
||||
struct tee_rpc_cmd {
|
||||
void *buffer;
|
||||
union {
|
||||
void *buffer;
|
||||
uint64_t padding_buf;
|
||||
};
|
||||
uint32_t size;
|
||||
uint32_t type;
|
||||
int fd;
|
||||
int reserved;
|
||||
};
|
||||
|
||||
struct tee_rpc_invoke {
|
||||
uint32_t cmd;
|
||||
uint32_t res;
|
||||
uint32_t nbr_bf;
|
||||
uint32_t reserved;
|
||||
struct tee_rpc_cmd cmds[TEE_RPC_BUFFER_NUMBER];
|
||||
};
|
||||
|
||||
|
|
@ -83,6 +88,7 @@ struct tee_rpc {
|
|||
struct tee_rpc_invoke commFromUser;
|
||||
struct semaphore datatouser;
|
||||
struct semaphore datafromuser;
|
||||
struct mutex thrd_mutex; /* Block the thread to wait for supp answer */
|
||||
struct mutex outsync; /* Out sync mutex */
|
||||
struct mutex insync; /* In sync mutex */
|
||||
struct mutex reqsync; /* Request sync mutex */
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
|
||||
/dts-v1/;
|
||||
|
||||
/memreserve/ 0x81000000 0x00100000;
|
||||
/memreserve/ 0x80000000 0x00010000;
|
||||
|
||||
/ {
|
||||
|
|
@ -96,6 +95,16 @@
|
|||
<0x00000008 0x80000000 0 0x80000000>;
|
||||
};
|
||||
|
||||
reserved-memory {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
|
||||
optee@0x83000000 {
|
||||
reg = <0x00000000 0x83000000 0 0x01000000>;
|
||||
};
|
||||
};
|
||||
|
||||
gic: interrupt-controller@2f000000 {
|
||||
compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
|
||||
#interrupt-cells = <3>;
|
||||
|
|
|
|||
|
|
@ -435,7 +435,7 @@ struct teesmc_meta_open_session {
|
|||
* r4-7/x4-7 Preserved
|
||||
*
|
||||
* Ebusy return register usage:
|
||||
* r0/x0 Return value, TEESMC_RETURN_EBUSY
|
||||
* r0/x0 Return value, TEESMC_RETURN_ETHREAD_LIMIT
|
||||
* r1-3/x1-3 Preserved
|
||||
* r4-7/x4-7 Preserved
|
||||
*
|
||||
|
|
@ -450,7 +450,8 @@ struct teesmc_meta_open_session {
|
|||
* TEESMC_RETURN_OK Call completed, result updated in
|
||||
* the previously supplied struct
|
||||
* teesmc32_arg.
|
||||
* TEESMC_RETURN_EBUSY Trusted OS busy, try again later.
|
||||
* TEESMC_RETURN_ETHREAD_LIMIT Trusted OS out of threads,
|
||||
* try again later.
|
||||
* TEESMC_RETURN_EBADADDR Bad physcial pointer to struct
|
||||
* teesmc32_arg.
|
||||
* TEESMC_RETURN_EBADCMD Bad/unknown cmd in struct teesmc32_arg
|
||||
|
|
@ -500,7 +501,8 @@ struct teesmc_meta_open_session {
|
|||
* struct teesmc32_arg
|
||||
* TEESMC_RETURN_RPC Call suspended by RPC call to normal
|
||||
* world.
|
||||
* TEESMC_RETURN_EBUSY Trusted OS busy, try again later.
|
||||
* TEESMC_RETURN_ETHREAD_LIMIT Trusted OS out of threads,
|
||||
* try again later.
|
||||
* TEESMC_RETURN_ERESUME Resume failed, the opaque resume
|
||||
* information was corrupt.
|
||||
*/
|
||||
|
|
@ -685,7 +687,7 @@ struct teesmc_meta_open_session {
|
|||
|
||||
/* Returned in r0 only from Trusted OS functions */
|
||||
#define TEESMC_RETURN_OK 0x0
|
||||
#define TEESMC_RETURN_EBUSY 0x1
|
||||
#define TEESMC_RETURN_ETHREAD_LIMIT 0x1
|
||||
#define TEESMC_RETURN_ERESUME 0x2
|
||||
#define TEESMC_RETURN_EBADADDR 0x3
|
||||
#define TEESMC_RETURN_EBADCMD 0x4
|
||||
|
|
|
|||
|
|
@ -269,6 +269,14 @@ typedef struct {
|
|||
uint8_t clockSeqAndNode[8];
|
||||
} TEEC_UUID;
|
||||
|
||||
/**
|
||||
* In terms of compatible kernel, the data struct shared by client application
|
||||
* and TEE driver should be restructrued in "compatible" rules. To keep GP's
|
||||
* standard in compatibility mode, the anonymous padding members are filled
|
||||
* in the struct definition below.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* struct TEEC_SharedMemory - Memory to transfer data between a client
|
||||
* application and trusted code.
|
||||
|
|
@ -286,18 +294,26 @@ typedef struct {
|
|||
* is responsible to populate the buffer pointer.
|
||||
*/
|
||||
typedef struct {
|
||||
void *buffer;
|
||||
size_t size;
|
||||
union {
|
||||
void *buffer;
|
||||
uint64_t padding_ptr;
|
||||
};
|
||||
union {
|
||||
size_t size;
|
||||
uint64_t padding_sz;
|
||||
};
|
||||
uint32_t flags;
|
||||
/*
|
||||
* identifier can store a handle (int) or a structure pointer (void *).
|
||||
* define this union to match case where sizeof(int)!=sizeof(void *).
|
||||
*/
|
||||
uint32_t reserved;
|
||||
union {
|
||||
int fd;
|
||||
void *ptr;
|
||||
uint64_t padding_d;
|
||||
} d;
|
||||
uint8_t registered;
|
||||
uint64_t registered;
|
||||
} TEEC_SharedMemory;
|
||||
|
||||
/**
|
||||
|
|
@ -313,8 +329,14 @@ typedef struct {
|
|||
* operation to be called.
|
||||
*/
|
||||
typedef struct {
|
||||
void *buffer;
|
||||
size_t size;
|
||||
union {
|
||||
void *buffer;
|
||||
uint64_t padding_ptr;
|
||||
};
|
||||
union {
|
||||
size_t size;
|
||||
uint64_t padding_sz;
|
||||
};
|
||||
} TEEC_TempMemoryReference;
|
||||
|
||||
/**
|
||||
|
|
@ -333,9 +355,18 @@ typedef struct {
|
|||
*
|
||||
*/
|
||||
typedef struct {
|
||||
TEEC_SharedMemory *parent;
|
||||
size_t size;
|
||||
size_t offset;
|
||||
union {
|
||||
TEEC_SharedMemory *parent;
|
||||
uint64_t padding_ptr;
|
||||
};
|
||||
union {
|
||||
size_t size;
|
||||
uint64_t padding_sz;
|
||||
};
|
||||
union {
|
||||
size_t offset;
|
||||
uint64_t padding_off;
|
||||
};
|
||||
} TEEC_RegisteredMemoryReference;
|
||||
|
||||
/**
|
||||
|
|
@ -400,9 +431,12 @@ typedef struct {
|
|||
uint32_t paramTypes;
|
||||
TEEC_Parameter params[TEEC_CONFIG_PAYLOAD_REF_COUNT];
|
||||
/* Implementation-Defined */
|
||||
TEEC_Session *session;
|
||||
union {
|
||||
TEEC_Session *session;
|
||||
uint64_t padding_ptr;
|
||||
};
|
||||
TEEC_SharedMemory memRefs[TEEC_CONFIG_PAYLOAD_REF_COUNT];
|
||||
uint32_t flags;
|
||||
uint64_t flags;
|
||||
} TEEC_Operation;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -36,22 +36,42 @@ struct tee_cmd_io {
|
|||
TEEC_Result err;
|
||||
uint32_t origin;
|
||||
uint32_t cmd;
|
||||
TEEC_UUID __user *uuid;
|
||||
void __user *data;
|
||||
uint32_t data_size;
|
||||
TEEC_Operation __user *op;
|
||||
int fd_sess;
|
||||
/*
|
||||
* Here fd_sess is 32-bit variable. Since TEEC_Result also is defined as
|
||||
* "uint32_t", this structure is aligned.
|
||||
*/
|
||||
union {
|
||||
TEEC_UUID __user *uuid;
|
||||
uint64_t padding_uuid;
|
||||
};
|
||||
union {
|
||||
void __user *data;
|
||||
uint64_t padding_data;
|
||||
};
|
||||
union {
|
||||
TEEC_Operation __user *op;
|
||||
uint64_t padding_op;
|
||||
};
|
||||
uint32_t data_size;
|
||||
int32_t reserved;
|
||||
};
|
||||
|
||||
struct tee_shm_io {
|
||||
void __user *buffer;
|
||||
size_t size;
|
||||
uint32_t flags;
|
||||
union {
|
||||
int fd_shm;
|
||||
void *ptr;
|
||||
void __user *buffer;
|
||||
uint64_t padding_buf;
|
||||
};
|
||||
uint8_t registered;
|
||||
uint32_t size;
|
||||
uint32_t flags;
|
||||
/*
|
||||
* Here fd_shm is 32-bit. To be compliant with the convention of file
|
||||
* descriptor definition, fd_shm is defined as "int" type other
|
||||
* than "int32_t". Even though using "int32_t" is more obvious to
|
||||
* indicate that we intend to keep this structure aligned.
|
||||
*/
|
||||
int fd_shm;
|
||||
uint32_t registered;
|
||||
};
|
||||
|
||||
#define TEE_OPEN_SESSION_IOC _IOWR('t', 161, struct tee_cmd_io)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue