mirror of
https://github.com/apache/nuttx.git
synced 2026-05-20 20:44:39 +08:00
drivers/misc/optee: Fix non-registered memory ref passing
So far the NuttX implementation of OP-TEE has been using registered memory references to pass non-registered memory to OP-TEE OS, passing the physical address of the memory in what is normally used as a 'cookie'. This was compatible with the Openvela framework, but no other OP-TEE OS. Fix this by passing temporary memory instead with the standard non-contiguous (OPTEE_MSG_ATTR_NONCONTIG) flag. Signed-off-by: George Poulios <gpoulios@census-labs.com>
This commit is contained in:
committed by
Xiang Xiao
parent
6f77cb6dce
commit
47064e42df
+53
-33
@@ -562,48 +562,53 @@ static int optee_memref_to_msg_param(FAR struct optee_priv_data *priv,
|
||||
FAR const struct tee_ioctl_param *p)
|
||||
{
|
||||
FAR struct optee_shm *shm;
|
||||
uintptr_t page_list_pa;
|
||||
|
||||
/* Warning: the case for non-registered memrefs below is a hack to work
|
||||
* with openvela. Normally, non-registered memory should be specified as
|
||||
* OPTEE_MSG_ATTR_TYPE_TMEM_* (note the 'T') and `buf_ptr` should be set
|
||||
* to the physical address of buffer.
|
||||
*
|
||||
* Related openvela patches:
|
||||
* - external_optee_optee_os@1a29df42 core/tee/entry_std.c#L160
|
||||
* - frameworks_security_optee_vela@54b377d5c compat/mobj_dyn_shm.c#L25
|
||||
*
|
||||
* Ideally, in the future, this should be wrapped around some
|
||||
* CONFIG_OPTEE_OPENVELA_COMPAT guard.
|
||||
*/
|
||||
|
||||
mp->attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT + p->attr -
|
||||
TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
|
||||
if (p->c != TEE_MEMREF_NULL)
|
||||
if (p->c == TEE_MEMREF_NULL)
|
||||
{
|
||||
shm = idr_find(priv->shms, p->c);
|
||||
if (shm == NULL)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
mp->attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT + p->attr -
|
||||
TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
|
||||
mp->u.tmem.buf_ptr = 0;
|
||||
mp->u.tmem.shm_ref = 0;
|
||||
mp->u.tmem.size = p->b;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (shm->flags & TEE_SHM_REGISTER)
|
||||
{
|
||||
mp->u.rmem.shm_ref = (uintptr_t)shm;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* hack to comply with openvela */
|
||||
shm = idr_find(priv->shms, p->c);
|
||||
if (shm == NULL)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mp->u.rmem.shm_ref = shm->addr;
|
||||
}
|
||||
if (shm->flags & TEE_SHM_REGISTER)
|
||||
{
|
||||
/* registered memory */
|
||||
|
||||
mp->attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT + p->attr -
|
||||
TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
|
||||
mp->u.rmem.offs = p->a;
|
||||
mp->u.rmem.size = p->b;
|
||||
mp->u.rmem.shm_ref = (uintptr_t)shm;
|
||||
}
|
||||
else
|
||||
{
|
||||
mp->u.rmem.shm_ref = 0;
|
||||
/* non-registered memory (temporary) */
|
||||
|
||||
mp->attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT + p->attr -
|
||||
TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
|
||||
mp->attr |= OPTEE_MSG_ATTR_NONCONTIG;
|
||||
|
||||
shm->page_list = optee_shm_to_page_list(shm, &page_list_pa);
|
||||
if (shm->page_list == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mp->u.tmem.buf_ptr = page_list_pa;
|
||||
mp->u.tmem.shm_ref = (uintptr_t)shm;
|
||||
mp->u.tmem.size = shm->length;
|
||||
}
|
||||
|
||||
mp->u.rmem.size = p->b;
|
||||
mp->u.rmem.offs = p->a;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -666,6 +671,7 @@ static int optee_from_msg_param(FAR struct tee_ioctl_param *params,
|
||||
{
|
||||
FAR const struct optee_msg_param *mp = mparams + n;
|
||||
FAR struct tee_ioctl_param *p = params + n;
|
||||
FAR struct optee_shm *shm;
|
||||
|
||||
switch (mp->attr & OPTEE_MSG_ATTR_TYPE_MASK)
|
||||
{
|
||||
@@ -684,6 +690,20 @@ static int optee_from_msg_param(FAR struct tee_ioctl_param *params,
|
||||
p->b = mp->u.value.b;
|
||||
p->c = mp->u.value.c;
|
||||
break;
|
||||
case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT:
|
||||
case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT:
|
||||
case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT:
|
||||
p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
|
||||
mp->attr - OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
|
||||
p->b = mp->u.tmem.size;
|
||||
|
||||
shm = (FAR struct optee_shm *)(uintptr_t)mp->u.tmem.shm_ref;
|
||||
if (shm && shm->page_list)
|
||||
{
|
||||
kmm_free(shm->page_list);
|
||||
shm->page_list = NULL;
|
||||
}
|
||||
break;
|
||||
case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT:
|
||||
case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
|
||||
case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT:
|
||||
|
||||
@@ -58,6 +58,7 @@ struct optee_shm
|
||||
int32_t id;
|
||||
uint64_t addr;
|
||||
uint64_t length;
|
||||
FAR void *page_list;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user