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