1 /* SPDX-License-Identifier: BSD-2-Clause */ 2 /* 3 * Copyright (c) 2014, STMicroelectronics International N.V. 4 * Copyright (c) 2020, Linaro Limited 5 */ 6 #ifndef __KERNEL_USER_ACCESS_H 7 #define __KERNEL_USER_ACCESS_H 8 9 #include <assert.h> 10 #include <kernel/user_access_arch.h> 11 #include <tee_api_types.h> 12 #include <types_ext.h> 13 14 #ifdef CFG_WITH_USER_TA 15 TEE_Result copy_from_user_private(void *kaddr, const void *uaddr, size_t len); 16 TEE_Result copy_from_user(void *kaddr, const void *uaddr, size_t len); 17 #else 18 static inline TEE_Result copy_from_user_private(void *kaddr __unused, 19 const void *uaddr __unused, 20 size_t len __unused) 21 { 22 return TEE_ERROR_NOT_SUPPORTED; 23 } 24 25 static inline TEE_Result copy_from_user(void *kaddr __unused, 26 const void *uaddr __unused, 27 size_t len __unused) 28 { 29 return TEE_ERROR_NOT_SUPPORTED; 30 } 31 32 #endif 33 34 /* 35 * bb_alloc() - Allocate a bounce buffer 36 * @len: Length of bounce buffer 37 * 38 * The bounce buffer is allocated from a per user TA context region reserved 39 * for bounce buffers. Buffers are allocated in a stack like fashion so 40 * only the last buffer can be free. Buffers generally don't have to be 41 * freed, all bounce buffer allocations are reset on each syscall entry. 42 * 43 * Return NULL on failure or a valid pointer on success. 44 */ 45 void *bb_alloc(size_t len); 46 47 /* 48 * bb_free() - Free a bounce buffer 49 * @bb: Buffer 50 * @len: Length of buffer 51 * 52 * The bounce buffer is only freed if it is last on the stack of allocated 53 * bounce buffers. This function does normally not need to be called, see 54 * description of bb_alloc(). 55 */ 56 void bb_free(void *bb, size_t len); 57 58 /* 59 * bb_reset() - Reset bounce buffer allocation 60 * 61 * Resets the bounce buffer allocatation state, old pointers allocated 62 * with bb_alloc() should not be used any longer. 63 */ 64 void bb_reset(void); 65 66 TEE_Result copy_to_user_private(void *uaddr, const void *kaddr, size_t len); 67 TEE_Result copy_to_user(void *uaddr, const void *kaddr, size_t len); 68 69 TEE_Result clear_user(void *uaddr, size_t n); 70 71 size_t strnlen_user(const void *s, size_t n); 72 73 /* 74 * bb_memdup_user() - Duplicate a user-space buffer into a bounce buffer 75 * @src: Pointer to the user buffer to be duplicated. 76 * @len: Length of the user buffer to be duplicated. 77 * @p: Holds duplicated bounce buffer on success, or unchanged on failure. 78 * Note that the returned buffer is allocated by bb_alloc() and 79 * normally doesn't have to be freed. 80 * Return TEE_SUCCESS on success. 81 * Return TEE_ERROR_OUT_OF_MEMORY or TEE_ERROR_ACCESS_DENIED on error. 82 */ 83 TEE_Result bb_memdup_user(const void *src, size_t len, void **p); 84 85 /* 86 * bb_memdup_user_private() - Duplicate a private user-space buffer 87 * @src: Pointer to the user buffer to be duplicated. The buffer should 88 * be private to current TA (i.e., !TEE_MEMORY_ACCESS_ANY_OWNER). 89 * @len: Length of the user buffer to be duplicated. 90 * @p: Holds duplicated kernel buffer on success, or unchanged on failure. 91 * Note that the returned buffer is allocated by bb_alloc() and 92 * normally doesn't have to be freed. 93 * Return TEE_SUCCESS on success. 94 * Return TEE_ERROR_OUT_OF_MEMORY or TEE_ERROR_ACCESS_DENIED on error. 95 */ 96 TEE_Result bb_memdup_user_private(const void *src, size_t len, void **p); 97 98 TEE_Result copy_kaddr_to_uref(uint32_t *uref, void *kaddr); 99 100 uint32_t kaddr_to_uref(void *kaddr); 101 vaddr_t uref_to_vaddr(uint32_t uref); 102 static inline void *uref_to_kaddr(uint32_t uref) 103 { 104 return (void *)uref_to_vaddr(uref); 105 } 106 107 #define GET_USER_SCALAR(_x, _p) ({ \ 108 TEE_Result __res = TEE_SUCCESS; \ 109 typeof(_p) __p = (_p); \ 110 \ 111 static_assert(sizeof(_x) == sizeof(*__p)); \ 112 \ 113 __res = copy_from_user(&(_x), (const void *)__p, sizeof(*__p)); \ 114 __res; \ 115 }) 116 117 #define PUT_USER_SCALAR(_x, _p) ({ \ 118 TEE_Result __res = TEE_SUCCESS; \ 119 typeof(_p) __p = (_p); \ 120 \ 121 static_assert(sizeof(_x) == sizeof(*__p)); \ 122 \ 123 __res = copy_to_user((void *)__p, &(_x), sizeof(*__p)); \ 124 __res; \ 125 }) 126 127 #endif /*__KERNEL_USER_ACCESS_H*/ 128