Commit | Line | Data |
---|---|---|
61d0b5a4 RR |
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 | ||
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 | ||
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 | ||
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 | ||
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 */ |