1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef UACCESS_H 3 #define UACCESS_H 4 5 #include <linux/compiler.h> 6 7 extern void *__user_addr_min, *__user_addr_max; 8 9 static inline void __chk_user_ptr(const volatile void *p, size_t size) 10 { 11 assert(p >= __user_addr_min && p + size <= __user_addr_max); 12 } 13 14 #define put_user(x, ptr) \ 15 ({ \ 16 typeof(ptr) __pu_ptr = (ptr); \ 17 __chk_user_ptr(__pu_ptr, sizeof(*__pu_ptr)); \ 18 WRITE_ONCE(*(__pu_ptr), x); \ 19 0; \ 20 }) 21 22 #define get_user(x, ptr) \ 23 ({ \ 24 typeof(ptr) __pu_ptr = (ptr); \ 25 __chk_user_ptr(__pu_ptr, sizeof(*__pu_ptr)); \ 26 x = READ_ONCE(*(__pu_ptr)); \ 27 0; \ 28 }) 29 30 static void volatile_memcpy(volatile char *to, const volatile char *from, 31 unsigned long n) 32 { 33 while (n--) 34 *(to++) = *(from++); 35 } 36 37 static inline int copy_from_user(void *to, const void __user volatile *from, 38 unsigned long n) 39 { 40 __chk_user_ptr(from, n); 41 volatile_memcpy(to, from, n); 42 return 0; 43 } 44 45 static inline int copy_to_user(void __user volatile *to, const void *from, 46 unsigned long n) 47 { 48 __chk_user_ptr(to, n); 49 volatile_memcpy(to, from, n); 50 return 0; 51 } 52 #endif /* UACCESS_H */ 53