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 <tkaratapanis@census-labs.com>
This commit is contained in:
Theodore Karatapanis 2025-07-16 13:11:08 +03:00 committed by Xiang Xiao
parent 7b3913da60
commit cbdd3ac39b
3 changed files with 11 additions and 11 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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