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_access(uint32_t flags, vaddr_t va, size_t len) 16 { 17 struct tee_ta_session *s = NULL; 18 TEE_Result res = tee_ta_get_current_session(&s); 19 20 if (res) 21 return res; 22 23 return tee_mmu_check_access_rights(&to_user_ta_ctx(s->ctx)->uctx, 24 flags, va, len); 25 } 26 27 TEE_Result copy_from_user(void *kaddr, const void *uaddr, size_t len) 28 { 29 uint32_t flags = TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_ANY_OWNER; 30 TEE_Result res = check_access(flags, (vaddr_t)uaddr, len); 31 32 if (!res) 33 memcpy(kaddr, uaddr, len); 34 35 return res; 36 } 37 38 TEE_Result copy_to_user(void *uaddr, const void *kaddr, size_t len) 39 { 40 uint32_t flags = TEE_MEMORY_ACCESS_WRITE | TEE_MEMORY_ACCESS_ANY_OWNER; 41 TEE_Result res = check_access(flags, (vaddr_t)uaddr, len); 42 43 if (!res) 44 memcpy(uaddr, kaddr, len); 45 46 return res; 47 } 48 49 TEE_Result copy_from_user_private(void *kaddr, const void *uaddr, size_t len) 50 { 51 uint32_t flags = TEE_MEMORY_ACCESS_READ; 52 TEE_Result res = check_access(flags, (vaddr_t)uaddr, len); 53 54 if (!res) 55 memcpy(kaddr, uaddr, len); 56 57 return res; 58 } 59 60 TEE_Result copy_to_user_private(void *uaddr, const void *kaddr, size_t len) 61 { 62 uint32_t flags = TEE_MEMORY_ACCESS_WRITE; 63 TEE_Result res = check_access(flags, (vaddr_t)uaddr, len); 64 65 if (!res) 66 memcpy(uaddr, kaddr, len); 67 68 return res; 69 } 70 71 TEE_Result copy_kaddr_to_uref(uint32_t *uref, void *kaddr) 72 { 73 uint32_t ref = kaddr_to_uref(kaddr); 74 75 return copy_to_user_private(uref, &ref, sizeof(ref)); 76 } 77 78 uint32_t kaddr_to_uref(void *kaddr) 79 { 80 assert(((vaddr_t)kaddr - VCORE_START_VA) < UINT32_MAX); 81 return (vaddr_t)kaddr - VCORE_START_VA; 82 } 83 84 vaddr_t uref_to_vaddr(uint32_t uref) 85 { 86 return VCORE_START_VA + uref; 87 } 88