Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
uaccess_32.h
Go to the documentation of this file.
1 #ifndef _ASM_X86_UACCESS_32_H
2 #define _ASM_X86_UACCESS_32_H
3 
4 /*
5  * User space memory access functions
6  */
7 #include <linux/errno.h>
8 #include <linux/thread_info.h>
9 #include <linux/string.h>
10 #include <asm/asm.h>
11 #include <asm/page.h>
12 
13 unsigned long __must_check __copy_to_user_ll
14  (void __user *to, const void *from, unsigned long n);
16  (void *to, const void __user *from, unsigned long n);
18  (void *to, const void __user *from, unsigned long n);
20  (void *to, const void __user *from, unsigned long n);
22  (void *to, const void __user *from, unsigned long n);
23 
43 static __always_inline unsigned long __must_check
44 __copy_to_user_inatomic(void __user *to, const void *from, unsigned long n)
45 {
46  if (__builtin_constant_p(n)) {
47  unsigned long ret;
48 
49  switch (n) {
50  case 1:
51  __put_user_size(*(u8 *)from, (u8 __user *)to,
52  1, ret, 1);
53  return ret;
54  case 2:
55  __put_user_size(*(u16 *)from, (u16 __user *)to,
56  2, ret, 2);
57  return ret;
58  case 4:
59  __put_user_size(*(u32 *)from, (u32 __user *)to,
60  4, ret, 4);
61  return ret;
62  }
63  }
64  return __copy_to_user_ll(to, from, n);
65 }
66 
81 static __always_inline unsigned long __must_check
82 __copy_to_user(void __user *to, const void *from, unsigned long n)
83 {
84  might_fault();
85  return __copy_to_user_inatomic(to, from, n);
86 }
87 
88 static __always_inline unsigned long
89 __copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
90 {
91  /* Avoid zeroing the tail if the copy fails..
92  * If 'n' is constant and 1, 2, or 4, we do still zero on a failure,
93  * but as the zeroing behaviour is only significant when n is not
94  * constant, that shouldn't be a problem.
95  */
96  if (__builtin_constant_p(n)) {
97  unsigned long ret;
98 
99  switch (n) {
100  case 1:
101  __get_user_size(*(u8 *)to, from, 1, ret, 1);
102  return ret;
103  case 2:
104  __get_user_size(*(u16 *)to, from, 2, ret, 2);
105  return ret;
106  case 4:
107  __get_user_size(*(u32 *)to, from, 4, ret, 4);
108  return ret;
109  }
110  }
111  return __copy_from_user_ll_nozero(to, from, n);
112 }
113 
136 static __always_inline unsigned long
137 __copy_from_user(void *to, const void __user *from, unsigned long n)
138 {
139  might_fault();
140  if (__builtin_constant_p(n)) {
141  unsigned long ret;
142 
143  switch (n) {
144  case 1:
145  __get_user_size(*(u8 *)to, from, 1, ret, 1);
146  return ret;
147  case 2:
148  __get_user_size(*(u16 *)to, from, 2, ret, 2);
149  return ret;
150  case 4:
151  __get_user_size(*(u32 *)to, from, 4, ret, 4);
152  return ret;
153  }
154  }
155  return __copy_from_user_ll(to, from, n);
156 }
157 
158 static __always_inline unsigned long __copy_from_user_nocache(void *to,
159  const void __user *from, unsigned long n)
160 {
161  might_fault();
162  if (__builtin_constant_p(n)) {
163  unsigned long ret;
164 
165  switch (n) {
166  case 1:
167  __get_user_size(*(u8 *)to, from, 1, ret, 1);
168  return ret;
169  case 2:
170  __get_user_size(*(u16 *)to, from, 2, ret, 2);
171  return ret;
172  case 4:
173  __get_user_size(*(u32 *)to, from, 4, ret, 4);
174  return ret;
175  }
176  }
177  return __copy_from_user_ll_nocache(to, from, n);
178 }
179 
180 static __always_inline unsigned long
181 __copy_from_user_inatomic_nocache(void *to, const void __user *from,
182  unsigned long n)
183 {
184  return __copy_from_user_ll_nocache_nozero(to, from, n);
185 }
186 
187 unsigned long __must_check copy_to_user(void __user *to,
188  const void *from, unsigned long n);
189 unsigned long __must_check _copy_from_user(void *to,
190  const void __user *from,
191  unsigned long n);
192 
193 
194 extern void copy_from_user_overflow(void)
195 #ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
196  __compiletime_error("copy_from_user() buffer size is not provably correct")
197 #else
198  __compiletime_warning("copy_from_user() buffer size is not provably correct")
199 #endif
200 ;
201 
202 static inline unsigned long __must_check copy_from_user(void *to,
203  const void __user *from,
204  unsigned long n)
205 {
206  int sz = __compiletime_object_size(to);
207 
208  if (likely(sz == -1 || sz >= n))
209  n = _copy_from_user(to, from, n);
210  else
212 
213  return n;
214 }
215 
216 #endif /* _ASM_X86_UACCESS_32_H */