aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/include/asm/uaccess_64.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/include/asm/uaccess_64.h')
-rw-r--r--arch/x86/include/asm/uaccess_64.h21
1 files changed, 16 insertions, 5 deletions
diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h
index 84210c479fca..dcaa0404cf7b 100644
--- a/arch/x86/include/asm/uaccess_64.h
+++ b/arch/x86/include/asm/uaccess_64.h
@@ -189,17 +189,28 @@ extern long __copy_user_nocache(void *dst, const void __user *src,
189 unsigned size, int zerorest); 189 unsigned size, int zerorest);
190 190
191static inline int __copy_from_user_nocache(void *dst, const void __user *src, 191static inline int __copy_from_user_nocache(void *dst, const void __user *src,
192 unsigned size) 192 unsigned size, unsigned long total)
193{ 193{
194 might_sleep(); 194 might_sleep();
195 return __copy_user_nocache(dst, src, size, 1); 195 /*
196 * In practice this limit means that large file write()s
197 * which get chunked to 4K copies get handled via
198 * non-temporal stores here. Smaller writes get handled
199 * via regular __copy_from_user():
200 */
201 if (likely(total >= PAGE_SIZE))
202 return __copy_user_nocache(dst, src, size, 1);
203 else
204 return __copy_from_user(dst, src, size);
196} 205}
197 206
198static inline int __copy_from_user_inatomic_nocache(void *dst, 207static inline int __copy_from_user_inatomic_nocache(void *dst,
199 const void __user *src, 208 const void __user *src, unsigned size, unsigned total)
200 unsigned size)
201{ 209{
202 return __copy_user_nocache(dst, src, size, 0); 210 if (likely(total >= PAGE_SIZE))
211 return __copy_user_nocache(dst, src, size, 0);
212 else
213 return __copy_from_user_inatomic(dst, src, size);
203} 214}
204 215
205unsigned long 216unsigned long