1c40a6505SJens Wiklander // SPDX-License-Identifier: BSD-2-Clause 2c40a6505SJens Wiklander /* 3c40a6505SJens Wiklander * Copyright (c) 2014, STMicroelectronics International N.V. 4c40a6505SJens Wiklander * Copyright (c) 2015-2020 Linaro Limited 5c40a6505SJens Wiklander */ 6c40a6505SJens Wiklander 7c40a6505SJens Wiklander #include <initcall.h> 8c40a6505SJens Wiklander #include <kernel/linker.h> 9c40a6505SJens Wiklander #include <kernel/user_access.h> 10c40a6505SJens Wiklander #include <mm/tee_mmu.h> 11c40a6505SJens Wiklander #include <string.h> 12c40a6505SJens Wiklander #include <tee_api_types.h> 13c40a6505SJens Wiklander #include <types_ext.h> 14c40a6505SJens Wiklander 15*7e4100f3SJens Wiklander static TEE_Result check_access(uint32_t flags, vaddr_t va, size_t len) 16c40a6505SJens Wiklander { 17*7e4100f3SJens Wiklander struct tee_ta_session *s = NULL; 18*7e4100f3SJens Wiklander TEE_Result res = tee_ta_get_current_session(&s); 19*7e4100f3SJens Wiklander 20*7e4100f3SJens Wiklander if (res) 21*7e4100f3SJens Wiklander return res; 22*7e4100f3SJens Wiklander 23*7e4100f3SJens Wiklander return tee_mmu_check_access_rights(&to_user_ta_ctx(s->ctx)->uctx, 24*7e4100f3SJens Wiklander flags, va, len); 25c40a6505SJens Wiklander } 26c40a6505SJens Wiklander 27c40a6505SJens Wiklander TEE_Result copy_from_user(void *kaddr, const void *uaddr, size_t len) 28c40a6505SJens Wiklander { 29*7e4100f3SJens Wiklander uint32_t flags = TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_ANY_OWNER; 30*7e4100f3SJens Wiklander TEE_Result res = check_access(flags, (vaddr_t)uaddr, len); 31c40a6505SJens Wiklander 32*7e4100f3SJens Wiklander if (!res) 33c40a6505SJens Wiklander memcpy(kaddr, uaddr, len); 34*7e4100f3SJens Wiklander 35*7e4100f3SJens Wiklander return res; 36c40a6505SJens Wiklander } 37c40a6505SJens Wiklander 38c40a6505SJens Wiklander TEE_Result copy_to_user(void *uaddr, const void *kaddr, size_t len) 39c40a6505SJens Wiklander { 40*7e4100f3SJens Wiklander uint32_t flags = TEE_MEMORY_ACCESS_WRITE | TEE_MEMORY_ACCESS_ANY_OWNER; 41*7e4100f3SJens Wiklander TEE_Result res = check_access(flags, (vaddr_t)uaddr, len); 42c40a6505SJens Wiklander 43*7e4100f3SJens Wiklander if (!res) 44c40a6505SJens Wiklander memcpy(uaddr, kaddr, len); 45*7e4100f3SJens Wiklander 46*7e4100f3SJens Wiklander return res; 47*7e4100f3SJens Wiklander } 48*7e4100f3SJens Wiklander 49*7e4100f3SJens Wiklander TEE_Result copy_from_user_private(void *kaddr, const void *uaddr, size_t len) 50*7e4100f3SJens Wiklander { 51*7e4100f3SJens Wiklander uint32_t flags = TEE_MEMORY_ACCESS_READ; 52*7e4100f3SJens Wiklander TEE_Result res = check_access(flags, (vaddr_t)uaddr, len); 53*7e4100f3SJens Wiklander 54*7e4100f3SJens Wiklander if (!res) 55*7e4100f3SJens Wiklander memcpy(kaddr, uaddr, len); 56*7e4100f3SJens Wiklander 57*7e4100f3SJens Wiklander return res; 58*7e4100f3SJens Wiklander } 59*7e4100f3SJens Wiklander 60*7e4100f3SJens Wiklander TEE_Result copy_to_user_private(void *uaddr, const void *kaddr, size_t len) 61*7e4100f3SJens Wiklander { 62*7e4100f3SJens Wiklander uint32_t flags = TEE_MEMORY_ACCESS_WRITE; 63*7e4100f3SJens Wiklander TEE_Result res = check_access(flags, (vaddr_t)uaddr, len); 64*7e4100f3SJens Wiklander 65*7e4100f3SJens Wiklander if (!res) 66*7e4100f3SJens Wiklander memcpy(uaddr, kaddr, len); 67*7e4100f3SJens Wiklander 68*7e4100f3SJens Wiklander return res; 69c40a6505SJens Wiklander } 70c40a6505SJens Wiklander 71c40a6505SJens Wiklander TEE_Result copy_kaddr_to_uref(uint32_t *uref, void *kaddr) 72c40a6505SJens Wiklander { 73c40a6505SJens Wiklander uint32_t ref = kaddr_to_uref(kaddr); 74c40a6505SJens Wiklander 75*7e4100f3SJens Wiklander return copy_to_user_private(uref, &ref, sizeof(ref)); 76c40a6505SJens Wiklander } 77c40a6505SJens Wiklander 78c40a6505SJens Wiklander uint32_t kaddr_to_uref(void *kaddr) 79c40a6505SJens Wiklander { 80c40a6505SJens Wiklander assert(((vaddr_t)kaddr - VCORE_START_VA) < UINT32_MAX); 81c40a6505SJens Wiklander return (vaddr_t)kaddr - VCORE_START_VA; 82c40a6505SJens Wiklander } 83c40a6505SJens Wiklander 84c40a6505SJens Wiklander vaddr_t uref_to_vaddr(uint32_t uref) 85c40a6505SJens Wiklander { 86c40a6505SJens Wiklander return VCORE_START_VA + uref; 87c40a6505SJens Wiklander } 88