From cbdd3ac39bccb0ac4f413f8786ad3c976323ff00 Mon Sep 17 00:00:00 2001 From: Theodore Karatapanis Date: Wed, 16 Jul 2025 13:11:08 +0300 Subject: [PATCH] drivers/misc/optee: Add virtual and physical address to sturct optee_shm The VA -> PA translation must be performed once, at allocation time, while the caller's virtual address space is known. If a second process later tries to translate the same VA from a different mapping, the calculated physical address can be wrong. Signed-off-by: Theodore Karatapanis --- drivers/misc/optee.c | 15 ++++++++------- drivers/misc/optee.h | 3 ++- drivers/misc/optee_smc.c | 4 +--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/misc/optee.c b/drivers/misc/optee.c index 665bc28209..d9c0428329 100644 --- a/drivers/misc/optee.c +++ b/drivers/misc/optee.c @@ -309,7 +309,7 @@ optee_shm_to_page_list(FAR struct optee_shm *shm, FAR uintptr_t *list_pa) uint32_t list_size; uint32_t i = 0; - pgoff = shm->addr & (pgsize - 1); + pgoff = shm->vaddr & (pgsize - 1); total_pages = (uint32_t)div_round_up(pgoff + shm->length, pgsize); list_size = div_round_up(total_pages, OPTEE_PAGES_ARRAY_LEN) * sizeof(struct optee_page_list_entry); @@ -326,7 +326,7 @@ optee_shm_to_page_list(FAR struct optee_shm *shm, FAR uintptr_t *list_pa) } list_entry = (FAR struct optee_page_list_entry *)list; - page = ALIGN_DOWN(shm->addr, pgsize); + page = ALIGN_DOWN(shm->vaddr, pgsize); while (total_pages) { list_entry->pages_array[i++] = optee_va_to_pa((FAR const void *)page); @@ -615,7 +615,7 @@ static int optee_memref_to_msg_param(FAR struct optee_priv_data *priv, } #ifndef CONFIG_ARCH_USE_MMU - up_clean_dcache(shm->addr, shm->addr + shm->length); + up_clean_dcache(shm->vaddr, shm->vaddr + shm->length); #endif return 0; @@ -728,7 +728,7 @@ static int optee_from_msg_param(FAR struct tee_ioctl_param *params, #ifndef CONFIG_ARCH_USE_MMU if (shm) { - up_invalidate_dcache(shm->addr, shm->addr + shm->length); + up_invalidate_dcache(shm->vaddr, shm->vaddr + shm->length); } #endif } @@ -1225,7 +1225,8 @@ int optee_shm_alloc(FAR struct optee_priv_data *priv, FAR void *addr, shm->fd = -1; shm->priv = priv; - shm->addr = (uintptr_t)ptr; + shm->vaddr = (uintptr_t)ptr; + shm->paddr = optee_va_to_pa((FAR void *)shm->vaddr); shm->length = size; shm->flags = flags; shm->id = idr_alloc(priv->shms, shm, 0, 0); @@ -1288,14 +1289,14 @@ void optee_shm_free(FAR struct optee_shm *shm) if (shm->flags & TEE_SHM_ALLOC) { - kmm_free((FAR void *)(uintptr_t)shm->addr); + kmm_free((FAR void *)(uintptr_t)shm->vaddr); } if (!(shm->flags & (TEE_SHM_ALLOC | TEE_SHM_REGISTER))) { /* allocated by optee_ioctl_shm_alloc(), need to unmap */ - munmap((FAR void *)(uintptr_t)shm->addr, shm->length); + munmap((FAR void *)(uintptr_t)shm->vaddr, shm->length); } idr_remove(shm->priv->shms, shm->id); diff --git a/drivers/misc/optee.h b/drivers/misc/optee.h index 57adf7180f..db09b4993f 100644 --- a/drivers/misc/optee.h +++ b/drivers/misc/optee.h @@ -56,7 +56,8 @@ struct optee_shm FAR struct optee_priv_data *priv; int fd; int32_t id; - uint64_t addr; + uint64_t vaddr; + uint64_t paddr; uint64_t length; FAR void *page_list; uint32_t flags; diff --git a/drivers/misc/optee_smc.c b/drivers/misc/optee_smc.c index 43a33aef96..740ef0f930 100644 --- a/drivers/misc/optee_smc.c +++ b/drivers/misc/optee_smc.c @@ -180,7 +180,6 @@ static void optee_smc_handle_rpc(FAR struct optee_priv_data *priv_, FAR smccc_res_t *par) { FAR struct optee_shm *shm; - uintptr_t shm_pa; uint32_t rpc_func; rpc_func = OPTEE_SMC_RETURN_GET_RPC_FUNC(par->a0); @@ -191,8 +190,7 @@ static void optee_smc_handle_rpc(FAR struct optee_priv_data *priv_, case OPTEE_SMC_RPC_FUNC_ALLOC: if (!optee_shm_alloc(priv_, NULL, par->a1, TEE_SHM_ALLOC, &shm)) { - shm_pa = optee_va_to_pa((FAR void *)(uintptr_t)shm->addr); - reg_pair_from_64(shm_pa, &par->a1, &par->a2); + reg_pair_from_64(shm->paddr, &par->a1, &par->a2); reg_pair_from_64((uintptr_t)shm, &par->a4, &par->a5); } else