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 
check_access(uint32_t flags,vaddr_t va,size_t len)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 
copy_from_user(void * kaddr,const void * uaddr,size_t len)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 
copy_to_user(void * uaddr,const void * kaddr,size_t len)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 
copy_from_user_private(void * kaddr,const void * uaddr,size_t len)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 
copy_to_user_private(void * uaddr,const void * kaddr,size_t len)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 
copy_kaddr_to_uref(uint32_t * uref,void * kaddr)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 
kaddr_to_uref(void * kaddr)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 
uref_to_vaddr(uint32_t uref)80 vaddr_t uref_to_vaddr(uint32_t uref)
81 {
82 	return VCORE_START_VA + uref;
83 }
84