0001
0002 #ifndef UACCESS_H
0003 #define UACCESS_H
0004
0005 #include <linux/compiler.h>
0006
0007 extern void *__user_addr_min, *__user_addr_max;
0008
0009 static inline void __chk_user_ptr(const volatile void *p, size_t size)
0010 {
0011 assert(p >= __user_addr_min && p + size <= __user_addr_max);
0012 }
0013
0014 #define put_user(x, ptr) \
0015 ({ \
0016 typeof(ptr) __pu_ptr = (ptr); \
0017 __chk_user_ptr(__pu_ptr, sizeof(*__pu_ptr)); \
0018 WRITE_ONCE(*(__pu_ptr), x); \
0019 0; \
0020 })
0021
0022 #define get_user(x, ptr) \
0023 ({ \
0024 typeof(ptr) __pu_ptr = (ptr); \
0025 __chk_user_ptr(__pu_ptr, sizeof(*__pu_ptr)); \
0026 x = READ_ONCE(*(__pu_ptr)); \
0027 0; \
0028 })
0029
0030 static void volatile_memcpy(volatile char *to, const volatile char *from,
0031 unsigned long n)
0032 {
0033 while (n--)
0034 *(to++) = *(from++);
0035 }
0036
0037 static inline int copy_from_user(void *to, const void __user volatile *from,
0038 unsigned long n)
0039 {
0040 __chk_user_ptr(from, n);
0041 volatile_memcpy(to, from, n);
0042 return 0;
0043 }
0044
0045 static inline int copy_to_user(void __user volatile *to, const void *from,
0046 unsigned long n)
0047 {
0048 __chk_user_ptr(to, n);
0049 volatile_memcpy(to, from, n);
0050 return 0;
0051 }
0052 #endif