|
@@ -65,19 +65,12 @@
|
|
|
*/
|
|
|
|
|
|
/* Assembly somewhat optimized copy routines */
|
|
|
-unsigned long __copy_from_user_hexagon(void *to, const void __user *from,
|
|
|
+unsigned long raw_copy_from_user(void *to, const void __user *from,
|
|
|
unsigned long n);
|
|
|
-unsigned long __copy_to_user_hexagon(void __user *to, const void *from,
|
|
|
+unsigned long raw_copy_to_user(void __user *to, const void *from,
|
|
|
unsigned long n);
|
|
|
-
|
|
|
-#define __copy_from_user(to, from, n) __copy_from_user_hexagon(to, from, n)
|
|
|
-#define __copy_to_user(to, from, n) __copy_to_user_hexagon(to, from, n)
|
|
|
-
|
|
|
-/*
|
|
|
- * XXX todo: some additonal performance gain is possible by
|
|
|
- * implementing __copy_to/from_user_inatomic, which is much
|
|
|
- * like __copy_to/from_user, but performs slightly less checking.
|
|
|
- */
|
|
|
+#define INLINE_COPY_FROM_USER
|
|
|
+#define INLINE_COPY_TO_USER
|
|
|
|
|
|
__kernel_size_t __clear_user_hexagon(void __user *dest, unsigned long count);
|
|
|
#define __clear_user(a, s) __clear_user_hexagon((a), (s))
|
|
@@ -104,10 +97,14 @@ static inline long hexagon_strncpy_from_user(char *dst, const char __user *src,
|
|
|
return -EFAULT;
|
|
|
|
|
|
if (res > n) {
|
|
|
- copy_from_user(dst, src, n);
|
|
|
+ long left = raw_copy_from_user(dst, src, n);
|
|
|
+ if (unlikely(left))
|
|
|
+ memset(dst + (n - left), 0, left);
|
|
|
return n;
|
|
|
} else {
|
|
|
- copy_from_user(dst, src, res);
|
|
|
+ long left = raw_copy_from_user(dst, src, res);
|
|
|
+ if (unlikely(left))
|
|
|
+ memset(dst + (res - left), 0, left);
|
|
|
return res-1;
|
|
|
}
|
|
|
}
|