Skip to content

Commit 589c0e1

Browse files
gpouliosxiaoxiang781216
authored andcommitted
drivers/misc/optee: Cache coherency when MMU is disabled
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>
1 parent 4a765b5 commit 589c0e1

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

drivers/misc/optee.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <fcntl.h>
2828
#include <nuttx/tee.h>
2929
#include <nuttx/nuttx.h>
30+
#include <nuttx/cache.h>
3031
#include <nuttx/drivers/optee.h>
3132
#include <nuttx/fs/fs.h>
3233
#include <nuttx/kmalloc.h>
@@ -345,6 +346,10 @@ optee_shm_to_page_list(FAR struct optee_shm *shm, FAR uintptr_t *list_pa)
345346
*list_pa = optee_va_to_pa(list) | pgoff;
346347
}
347348

349+
#ifndef CONFIG_ARCH_USE_MMU
350+
up_clean_dcache((uintptr_t)list, (uintptr_t)list + list_size);
351+
#endif
352+
348353
return list;
349354
}
350355

@@ -609,6 +614,10 @@ static int optee_memref_to_msg_param(FAR struct optee_priv_data *priv,
609614
mp->u.tmem.size = shm->length;
610615
}
611616

617+
#ifndef CONFIG_ARCH_USE_MMU
618+
up_clean_dcache(shm->addr, shm->addr + shm->length);
619+
#endif
620+
612621
return 0;
613622
}
614623

@@ -671,7 +680,7 @@ static int optee_from_msg_param(FAR struct tee_ioctl_param *params,
671680
{
672681
FAR const struct optee_msg_param *mp = mparams + n;
673682
FAR struct tee_ioctl_param *p = params + n;
674-
FAR struct optee_shm *shm;
683+
FAR struct optee_shm *shm = NULL;
675684

676685
switch (mp->attr & OPTEE_MSG_ATTR_TYPE_MASK)
677686
{
@@ -710,10 +719,18 @@ static int optee_from_msg_param(FAR struct tee_ioctl_param *params,
710719
p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
711720
mp->attr - OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
712721
p->b = mp->u.rmem.size;
722+
shm = (FAR struct optee_shm *)(uintptr_t)mp->u.tmem.shm_ref;
713723
break;
714724
default:
715725
return -EINVAL;
716726
}
727+
728+
#ifndef CONFIG_ARCH_USE_MMU
729+
if (shm)
730+
{
731+
up_invalidate_dcache(shm->addr, shm->addr + shm->length);
732+
}
733+
#endif
717734
}
718735

719736
return 0;

drivers/misc/optee_smc.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
* Included Files
2525
****************************************************************************/
2626

27+
#include <nuttx/cache.h>
2728
#include <nuttx/kmalloc.h>
2829
#include <errno.h>
2930
#include <syslog.h>
@@ -314,11 +315,17 @@ int optee_transport_call(FAR struct optee_priv_data *priv_,
314315
smccc_res_t res;
315316
smccc_res_t par;
316317
uintptr_t arg_pa;
318+
#ifndef CONFIG_ARCH_USE_MMU
319+
size_t arg_size = OPTEE_MSG_GET_ARG_SIZE(arg->num_params);
320+
321+
up_clean_dcache((uintptr_t)arg, (uintptr_t)arg + arg_size);
322+
#endif
317323

318324
memset(&par, 0, sizeof(smccc_res_t));
319325

320326
par.a0 = OPTEE_SMC_CALL_WITH_ARG;
321327
arg_pa = optee_va_to_pa(arg);
328+
322329
reg_pair_from_64(arg_pa, &par.a1, &par.a2);
323330

324331
for (; ; )
@@ -335,6 +342,9 @@ int optee_transport_call(FAR struct optee_priv_data *priv_,
335342
}
336343
else
337344
{
345+
#ifndef CONFIG_ARCH_USE_MMU
346+
up_invalidate_dcache((uintptr_t)arg, (uintptr_t)arg + arg_size);
347+
#endif
338348
return (int)res.a0;
339349
}
340350
}

0 commit comments

Comments
 (0)