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 <kernel/user_mode_ctx.h> 11 #include <mm/vm.h> 12 #include <string.h> 13 #include <tee_api_types.h> 14 #include <types_ext.h> 15 16 static TEE_Result check_access(uint32_t flags, vaddr_t va, size_t len) 17 { 18 struct ts_session *s = ts_get_current_session(); 19 20 return vm_check_access_rights(to_user_mode_ctx(s->ctx), flags, va, len); 21 } 22 23 TEE_Result copy_from_user(void *kaddr, const void *uaddr, size_t len) 24 { 25 uint32_t flags = TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_ANY_OWNER; 26 TEE_Result res = check_access(flags, (vaddr_t)uaddr, len); 27 28 if (!res) 29 memcpy(kaddr, uaddr, len); 30 31 return res; 32 } 33 34 TEE_Result copy_to_user(void *uaddr, const void *kaddr, size_t len) 35 { 36 uint32_t flags = TEE_MEMORY_ACCESS_WRITE | TEE_MEMORY_ACCESS_ANY_OWNER; 37 TEE_Result res = check_access(flags, (vaddr_t)uaddr, len); 38 39 if (!res) 40 memcpy(uaddr, kaddr, len); 41 42 return res; 43 } 44 45 TEE_Result copy_from_user_private(void *kaddr, const void *uaddr, size_t len) 46 { 47 uint32_t flags = TEE_MEMORY_ACCESS_READ; 48 TEE_Result res = check_access(flags, (vaddr_t)uaddr, len); 49 50 if (!res) 51 memcpy(kaddr, uaddr, len); 52 53 return res; 54 } 55 56 TEE_Result copy_to_user_private(void *uaddr, const void *kaddr, size_t len) 57 { 58 uint32_t flags = TEE_MEMORY_ACCESS_WRITE; 59 TEE_Result res = check_access(flags, (vaddr_t)uaddr, len); 60 61 if (!res) 62 memcpy(uaddr, kaddr, len); 63 64 return res; 65 } 66 67 TEE_Result copy_kaddr_to_uref(uint32_t *uref, void *kaddr) 68 { 69 uint32_t ref = kaddr_to_uref(kaddr); 70 71 return copy_to_user_private(uref, &ref, sizeof(ref)); 72 } 73 74 uint32_t kaddr_to_uref(void *kaddr) 75 { 76 assert(((vaddr_t)kaddr - VCORE_START_VA) < UINT32_MAX); 77 return (vaddr_t)kaddr - VCORE_START_VA; 78 } 79 80 vaddr_t uref_to_vaddr(uint32_t uref) 81 { 82 return VCORE_START_VA + uref; 83 } 84