drivers/misc/optee: Cache coherency when MMU is disabled
Build Documentation / build-html (push) Has been cancelled

When the MMU is disabled (CONFIG_ARCH_USE_MMU=n) the
data passed back and forth with the TEE needs to be
synced from/to the cache, otherwise we get random data
in either world.

Fix this by cleaning before a call and invalidating after.
This has to be done both on the optee msg arg, and the shm
buffers therein. Cleaning and invalidating the page list
used to describe non-contiguous shm buffers did not seem
mandatory in my tests, but common sense says that it should
be, so we do that too.

This fix does not apply to the optee msg arg of the socket
transport (optee_socket.c), as that one _should_ be handled
by the socket send/recv methods. It does apply to all shm
buffers though, regardless of transport.

Signed-off-by: George Poulios <gpoulios@census-labs.com>
This commit is contained in:
George Poulios
2025-07-15 17:53:21 +03:00
committed by Xiang Xiao
parent 4a765b557f
commit 589c0e13b8
2 changed files with 28 additions and 1 deletions
+18 -1
View File
@@ -27,6 +27,7 @@
#include <fcntl.h>
#include <nuttx/tee.h>
#include <nuttx/nuttx.h>
#include <nuttx/cache.h>
#include <nuttx/drivers/optee.h>
#include <nuttx/fs/fs.h>
#include <nuttx/kmalloc.h>
@@ -345,6 +346,10 @@ optee_shm_to_page_list(FAR struct optee_shm *shm, FAR uintptr_t *list_pa)
*list_pa = optee_va_to_pa(list) | pgoff;
}
#ifndef CONFIG_ARCH_USE_MMU
up_clean_dcache((uintptr_t)list, (uintptr_t)list + list_size);
#endif
return list;
}
@@ -609,6 +614,10 @@ static int optee_memref_to_msg_param(FAR struct optee_priv_data *priv,
mp->u.tmem.size = shm->length;
}
#ifndef CONFIG_ARCH_USE_MMU
up_clean_dcache(shm->addr, shm->addr + shm->length);
#endif
return 0;
}
@@ -671,7 +680,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;
FAR struct optee_shm *shm = NULL;
switch (mp->attr & OPTEE_MSG_ATTR_TYPE_MASK)
{
@@ -710,10 +719,18 @@ static int optee_from_msg_param(FAR struct tee_ioctl_param *params,
p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
mp->attr - OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
p->b = mp->u.rmem.size;
shm = (FAR struct optee_shm *)(uintptr_t)mp->u.tmem.shm_ref;
break;
default:
return -EINVAL;
}
#ifndef CONFIG_ARCH_USE_MMU
if (shm)
{
up_invalidate_dcache(shm->addr, shm->addr + shm->length);
}
#endif
}
return 0;
+10
View File
@@ -24,6 +24,7 @@
* Included Files
****************************************************************************/
#include <nuttx/cache.h>
#include <nuttx/kmalloc.h>
#include <errno.h>
#include <syslog.h>
@@ -314,11 +315,17 @@ int optee_transport_call(FAR struct optee_priv_data *priv_,
smccc_res_t res;
smccc_res_t par;
uintptr_t arg_pa;
#ifndef CONFIG_ARCH_USE_MMU
size_t arg_size = OPTEE_MSG_GET_ARG_SIZE(arg->num_params);
up_clean_dcache((uintptr_t)arg, (uintptr_t)arg + arg_size);
#endif
memset(&par, 0, sizeof(smccc_res_t));
par.a0 = OPTEE_SMC_CALL_WITH_ARG;
arg_pa = optee_va_to_pa(arg);
reg_pair_from_64(arg_pa, &par.a1, &par.a2);
for (; ; )
@@ -335,6 +342,9 @@ int optee_transport_call(FAR struct optee_priv_data *priv_,
}
else
{
#ifndef CONFIG_ARCH_USE_MMU
up_invalidate_dcache((uintptr_t)arg, (uintptr_t)arg + arg_size);
#endif
return (int)res.a0;
}
}