diff options
Diffstat (limited to 'tools/virtio/linux/uaccess.h')
-rw-r--r-- | tools/virtio/linux/uaccess.h | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/tools/virtio/linux/uaccess.h b/tools/virtio/linux/uaccess.h new file mode 100644 index 000000000000..0a578fe18653 --- /dev/null +++ b/tools/virtio/linux/uaccess.h | |||
@@ -0,0 +1,50 @@ | |||
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 */ | ||