xref: /optee_os/core/kernel/user_access.c (revision c185655eafaab6b4b27759812cd6633e1da9db12)
1c40a6505SJens Wiklander // SPDX-License-Identifier: BSD-2-Clause
2c40a6505SJens Wiklander /*
3c40a6505SJens Wiklander  * Copyright (c) 2014, STMicroelectronics International N.V.
4c40a6505SJens Wiklander  * Copyright (c) 2015-2020 Linaro Limited
5c40a6505SJens Wiklander  */
6c40a6505SJens Wiklander 
7c40a6505SJens Wiklander #include <initcall.h>
8c40a6505SJens Wiklander #include <kernel/linker.h>
9c40a6505SJens Wiklander #include <kernel/user_access.h>
10*c185655eSJelle Sels #include <kernel/user_mode_ctx.h>
1189c9728dSJens Wiklander #include <mm/vm.h>
12c40a6505SJens Wiklander #include <string.h>
13c40a6505SJens Wiklander #include <tee_api_types.h>
14c40a6505SJens Wiklander #include <types_ext.h>
15c40a6505SJens Wiklander 
167e4100f3SJens Wiklander static TEE_Result check_access(uint32_t flags, vaddr_t va, size_t len)
17c40a6505SJens Wiklander {
1800b3b9a2SJens Wiklander 	struct ts_session *s = ts_get_current_session();
197e4100f3SJens Wiklander 
20*c185655eSJelle Sels 	return vm_check_access_rights(to_user_mode_ctx(s->ctx), flags, va, len);
21c40a6505SJens Wiklander }
22c40a6505SJens Wiklander 
23c40a6505SJens Wiklander TEE_Result copy_from_user(void *kaddr, const void *uaddr, size_t len)
24c40a6505SJens Wiklander {
257e4100f3SJens Wiklander 	uint32_t flags = TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_ANY_OWNER;
267e4100f3SJens Wiklander 	TEE_Result res = check_access(flags, (vaddr_t)uaddr, len);
27c40a6505SJens Wiklander 
287e4100f3SJens Wiklander 	if (!res)
29c40a6505SJens Wiklander 		memcpy(kaddr, uaddr, len);
307e4100f3SJens Wiklander 
317e4100f3SJens Wiklander 	return res;
32c40a6505SJens Wiklander }
33c40a6505SJens Wiklander 
34c40a6505SJens Wiklander TEE_Result copy_to_user(void *uaddr, const void *kaddr, size_t len)
35c40a6505SJens Wiklander {
367e4100f3SJens Wiklander 	uint32_t flags = TEE_MEMORY_ACCESS_WRITE | TEE_MEMORY_ACCESS_ANY_OWNER;
377e4100f3SJens Wiklander 	TEE_Result res = check_access(flags, (vaddr_t)uaddr, len);
38c40a6505SJens Wiklander 
397e4100f3SJens Wiklander 	if (!res)
40c40a6505SJens Wiklander 		memcpy(uaddr, kaddr, len);
417e4100f3SJens Wiklander 
427e4100f3SJens Wiklander 	return res;
437e4100f3SJens Wiklander }
447e4100f3SJens Wiklander 
457e4100f3SJens Wiklander TEE_Result copy_from_user_private(void *kaddr, const void *uaddr, size_t len)
467e4100f3SJens Wiklander {
477e4100f3SJens Wiklander 	uint32_t flags = TEE_MEMORY_ACCESS_READ;
487e4100f3SJens Wiklander 	TEE_Result res = check_access(flags, (vaddr_t)uaddr, len);
497e4100f3SJens Wiklander 
507e4100f3SJens Wiklander 	if (!res)
517e4100f3SJens Wiklander 		memcpy(kaddr, uaddr, len);
527e4100f3SJens Wiklander 
537e4100f3SJens Wiklander 	return res;
547e4100f3SJens Wiklander }
557e4100f3SJens Wiklander 
567e4100f3SJens Wiklander TEE_Result copy_to_user_private(void *uaddr, const void *kaddr, size_t len)
577e4100f3SJens Wiklander {
587e4100f3SJens Wiklander 	uint32_t flags = TEE_MEMORY_ACCESS_WRITE;
597e4100f3SJens Wiklander 	TEE_Result res = check_access(flags, (vaddr_t)uaddr, len);
607e4100f3SJens Wiklander 
617e4100f3SJens Wiklander 	if (!res)
627e4100f3SJens Wiklander 		memcpy(uaddr, kaddr, len);
637e4100f3SJens Wiklander 
647e4100f3SJens Wiklander 	return res;
65c40a6505SJens Wiklander }
66c40a6505SJens Wiklander 
67c40a6505SJens Wiklander TEE_Result copy_kaddr_to_uref(uint32_t *uref, void *kaddr)
68c40a6505SJens Wiklander {
69c40a6505SJens Wiklander 	uint32_t ref = kaddr_to_uref(kaddr);
70c40a6505SJens Wiklander 
717e4100f3SJens Wiklander 	return copy_to_user_private(uref, &ref, sizeof(ref));
72c40a6505SJens Wiklander }
73c40a6505SJens Wiklander 
74c40a6505SJens Wiklander uint32_t kaddr_to_uref(void *kaddr)
75c40a6505SJens Wiklander {
76c40a6505SJens Wiklander 	assert(((vaddr_t)kaddr - VCORE_START_VA) < UINT32_MAX);
77c40a6505SJens Wiklander 	return (vaddr_t)kaddr - VCORE_START_VA;
78c40a6505SJens Wiklander }
79c40a6505SJens Wiklander 
80c40a6505SJens Wiklander vaddr_t uref_to_vaddr(uint32_t uref)
81c40a6505SJens Wiklander {
82c40a6505SJens Wiklander 	return VCORE_START_VA + uref;
83c40a6505SJens Wiklander }
84