1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 4 * 5 * Derived from MIPS: 6 * Copyright (C) 1996, 1997, 1998, 1999, 2000, 03, 04 by Ralf Baechle 7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 8 * Copyright (C) 2007 Maciej W. Rozycki 9 * Copyright (C) 2014, Imagination Technologies Ltd. 10 */ 11 #ifndef _ASM_UACCESS_H 12 #define _ASM_UACCESS_H 13 14 #include <linux/kernel.h> 15 #include <linux/string.h> 16 #include <linux/extable.h> 17 #include <asm/pgtable.h> 18 #include <asm/extable.h> 19 #include <asm/asm-extable.h> 20 #include <asm-generic/access_ok.h> 21 22 #define __LSW 0 23 #define __MSW 1 24 25 extern u64 __ua_limit; 26 27 #ifdef CONFIG_64BIT 28 #define __UA_LIMIT __ua_limit 29 #else 30 #define __UA_LIMIT 0x80000000UL 31 #endif 32 33 /* 34 * get_user: - Get a simple variable from user space. 35 * @x: Variable to store result. 36 * @ptr: Source address, in user space. 37 * 38 * Context: User context only. This function may sleep if pagefaults are 39 * enabled. 40 * 41 * This macro copies a single simple variable from user space to kernel 42 * space. It supports simple types like char and int, but not larger 43 * data types like structures or arrays. 44 * 45 * @ptr must have pointer-to-simple-variable type, and the result of 46 * dereferencing @ptr must be assignable to @x without a cast. 47 * 48 * Returns zero on success, or -EFAULT on error. 49 * On error, the variable @x is set to zero. 50 */ 51 #define get_user(x, ptr) \ 52 ({ \ 53 const __typeof__(*(ptr)) __user *__p = (ptr); \ 54 \ 55 might_fault(); \ 56 access_ok(__p, sizeof(*__p)) ? __get_user((x), __p) : \ 57 ((x) = 0, -EFAULT); \ 58 }) 59 60 /* 61 * put_user: - Write a simple value into user space. 62 * @x: Value to copy to user space. 63 * @ptr: Destination address, in user space. 64 * 65 * Context: User context only. This function may sleep if pagefaults are 66 * enabled. 67 * 68 * This macro copies a single simple value from kernel space to user 69 * space. It supports simple types like char and int, but not larger 70 * data types like structures or arrays. 71 * 72 * @ptr must have pointer-to-simple-variable type, and @x must be assignable 73 * to the result of dereferencing @ptr. 74 * 75 * Returns zero on success, or -EFAULT on error. 76 */ 77 #define put_user(x, ptr) \ 78 ({ \ 79 __typeof__(*(ptr)) __user *__p = (ptr); \ 80 \ 81 might_fault(); \ 82 access_ok(__p, sizeof(*__p)) ? __put_user((x), __p) : -EFAULT; \ 83 }) 84 85 /* 86 * __get_user: - Get a simple variable from user space, with less checking. 87 * @x: Variable to store result. 88 * @ptr: Source address, in user space. 89 * 90 * Context: User context only. This function may sleep if pagefaults are 91 * enabled. 92 * 93 * This macro copies a single simple variable from user space to kernel 94 * space. It supports simple types like char and int, but not larger 95 * data types like structures or arrays. 96 * 97 * @ptr must have pointer-to-simple-variable type, and the result of 98 * dereferencing @ptr must be assignable to @x without a cast. 99 * 100 * Caller must check the pointer with access_ok() before calling this 101 * function. 102 * 103 * Returns zero on success, or -EFAULT on error. 104 * On error, the variable @x is set to zero. 105 */ 106 #define __get_user(x, ptr) \ 107 ({ \ 108 int __gu_err = 0; \ 109 \ 110 __chk_user_ptr(ptr); \ 111 __get_user_common((x), sizeof(*(ptr)), ptr); \ 112 __gu_err; \ 113 }) 114 115 /* 116 * __put_user: - Write a simple value into user space, with less checking. 117 * @x: Value to copy to user space. 118 * @ptr: Destination address, in user space. 119 * 120 * Context: User context only. This function may sleep if pagefaults are 121 * enabled. 122 * 123 * This macro copies a single simple value from kernel space to user 124 * space. It supports simple types like char and int, but not larger 125 * data types like structures or arrays. 126 * 127 * @ptr must have pointer-to-simple-variable type, and @x must be assignable 128 * to the result of dereferencing @ptr. 129 * 130 * Caller must check the pointer with access_ok() before calling this 131 * function. 132 * 133 * Returns zero on success, or -EFAULT on error. 134 */ 135 136 #define __put_user(x, ptr) \ 137 ({ \ 138 int __pu_err = 0; \ 139 __typeof__(*(ptr)) __pu_val; \ 140 \ 141 __pu_val = (x); \ 142 __chk_user_ptr(ptr); \ 143 __put_user_common(ptr, sizeof(*(ptr))); \ 144 __pu_err; \ 145 }) 146 147 struct __large_struct { unsigned long buf[100]; }; 148 #define __m(x) (*(struct __large_struct __user *)(x)) 149 150 #define __get_user_common(val, size, ptr) \ 151 do { \ 152 switch (size) { \ 153 case 1: __get_data_asm(val, "ld.b", ptr); break; \ 154 case 2: __get_data_asm(val, "ld.h", ptr); break; \ 155 case 4: __get_data_asm(val, "ld.w", ptr); break; \ 156 case 8: __get_data_asm_8(val, ptr); break; \ 157 default: BUILD_BUG(); break; \ 158 } \ 159 } while (0) 160 161 #define __get_kernel_common(val, size, ptr) __get_user_common(val, size, ptr) 162 163 #define __get_data_asm(val, insn, ptr) \ 164 { \ 165 long __gu_tmp; \ 166 \ 167 __asm__ __volatile__( \ 168 "1: " insn " %1, %2 \n" \ 169 "2: \n" \ 170 _ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 2b, %0, %1) \ 171 : "+r" (__gu_err), "=r" (__gu_tmp) \ 172 : "m" (__m(ptr))); \ 173 \ 174 (val) = (__typeof__(*(ptr))) __gu_tmp; \ 175 } 176 177 #ifdef CONFIG_64BIT 178 #define __get_data_asm_8(val, ptr) \ 179 __get_data_asm(val, "ld.d", ptr) 180 #else /* !CONFIG_64BIT */ 181 #define __get_data_asm_8(val, ptr) \ 182 { \ 183 u32 __lo, __hi; \ 184 u32 __user *__ptr = (u32 __user *)(ptr); \ 185 \ 186 __asm__ __volatile__ ( \ 187 "1:\n" \ 188 " ld.w %1, %3 \n" \ 189 "2:\n" \ 190 " ld.w %2, %4 \n" \ 191 "3:\n" \ 192 _ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 3b, %0, %1) \ 193 _ASM_EXTABLE_UACCESS_ERR_ZERO(2b, 3b, %0, %1) \ 194 : "+r" (__gu_err), "=&r" (__lo), "=r" (__hi) \ 195 : "m" (__ptr[__LSW]), "m" (__ptr[__MSW])); \ 196 if (__gu_err) \ 197 __hi = 0; \ 198 (val) = (__typeof__(val))((__typeof__((val)-(val))) \ 199 ((((u64)__hi << 32) | __lo))); \ 200 } 201 #endif /* CONFIG_64BIT */ 202 203 #define __put_user_common(ptr, size) \ 204 do { \ 205 switch (size) { \ 206 case 1: __put_data_asm("st.b", ptr); break; \ 207 case 2: __put_data_asm("st.h", ptr); break; \ 208 case 4: __put_data_asm("st.w", ptr); break; \ 209 case 8: __put_data_asm_8(ptr); break; \ 210 default: BUILD_BUG(); break; \ 211 } \ 212 } while (0) 213 214 #define __put_kernel_common(ptr, size) __put_user_common(ptr, size) 215 216 #define __put_data_asm(insn, ptr) \ 217 { \ 218 __asm__ __volatile__( \ 219 "1: " insn " %z2, %1 # __put_user_asm\n" \ 220 "2: \n" \ 221 _ASM_EXTABLE_UACCESS_ERR(1b, 2b, %0) \ 222 : "+r" (__pu_err), "=m" (__m(ptr)) \ 223 : "Jr" (__pu_val)); \ 224 } 225 226 #ifdef CONFIG_64BIT 227 #define __put_data_asm_8(ptr) \ 228 __put_data_asm("st.d", ptr) 229 #else /* !CONFIG_64BIT */ 230 #define __put_data_asm_8(ptr) \ 231 { \ 232 u32 __user *__ptr = (u32 __user *)(ptr); \ 233 u64 __x = (__typeof__((__pu_val)-(__pu_val)))(__pu_val); \ 234 \ 235 __asm__ __volatile__ ( \ 236 "1:\n" \ 237 " st.w %z3, %1 \n" \ 238 "2:\n" \ 239 " st.w %z4, %2 \n" \ 240 "3:\n" \ 241 _ASM_EXTABLE_UACCESS_ERR(1b, 3b, %0) \ 242 _ASM_EXTABLE_UACCESS_ERR(2b, 3b, %0) \ 243 : "+r" (__pu_err), \ 244 "=m" (__ptr[__LSW]), \ 245 "=m" (__ptr[__MSW]) \ 246 : "rJ" (__x), "rJ" (__x >> 32)); \ 247 } 248 #endif /* CONFIG_64BIT */ 249 250 #define __get_kernel_nofault(dst, src, type, err_label) \ 251 do { \ 252 int __gu_err = 0; \ 253 \ 254 __get_kernel_common(*((type *)(dst)), sizeof(type), \ 255 (__force type *)(src)); \ 256 if (unlikely(__gu_err)) \ 257 goto err_label; \ 258 } while (0) 259 260 #define __put_kernel_nofault(dst, src, type, err_label) \ 261 do { \ 262 type __pu_val; \ 263 int __pu_err = 0; \ 264 \ 265 __pu_val = *(__force type *)(src); \ 266 __put_kernel_common(((type *)(dst)), sizeof(type)); \ 267 if (unlikely(__pu_err)) \ 268 goto err_label; \ 269 } while (0) 270 271 extern unsigned long __copy_user(void *to, const void *from, __kernel_size_t n); 272 273 static inline unsigned long __must_check 274 raw_copy_from_user(void *to, const void __user *from, unsigned long n) 275 { 276 return __copy_user(to, (__force const void *)from, n); 277 } 278 279 static inline unsigned long __must_check 280 raw_copy_to_user(void __user *to, const void *from, unsigned long n) 281 { 282 return __copy_user((__force void *)to, from, n); 283 } 284 285 #define INLINE_COPY_FROM_USER 286 #define INLINE_COPY_TO_USER 287 288 /* 289 * __clear_user: - Zero a block of memory in user space, with less checking. 290 * @addr: Destination address, in user space. 291 * @size: Number of bytes to zero. 292 * 293 * Zero a block of memory in user space. Caller must check 294 * the specified block with access_ok() before calling this function. 295 * 296 * Returns number of bytes that could not be cleared. 297 * On success, this will be zero. 298 */ 299 extern unsigned long __clear_user(void __user *addr, __kernel_size_t size); 300 301 #define clear_user(addr, n) \ 302 ({ \ 303 void __user *__cl_addr = (addr); \ 304 unsigned long __cl_size = (n); \ 305 if (__cl_size && access_ok(__cl_addr, __cl_size)) \ 306 __cl_size = __clear_user(__cl_addr, __cl_size); \ 307 __cl_size; \ 308 }) 309 310 extern long strncpy_from_user(char *to, const char __user *from, long n); 311 extern long strnlen_user(const char __user *str, long n); 312 313 #endif /* _ASM_UACCESS_H */ 314