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