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