xref: /optee_os/core/kernel/user_access.c (revision c40a65057606debb80f0d467c956561a3cb550e9)
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