summaryrefslogtreecommitdiff
path: root/include/asm-generic
diff options
context:
space:
mode:
authorArun Sharma <arun.sharma@intel.com>2004-08-26 20:43:14 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-08-26 20:43:14 -0700
commitce18373907856aedaa6251ff3cdd1340ee4af29a (patch)
treef6067623ca7a61bc55b122b90c90d147732e5615 /include/asm-generic
parentfec18575fbb0faf522afbf5b5288962a79ed542f (diff)
[PATCH] Fix copying of unaligned data across user/kernel boundary
32 bit compatibility code sometimes needs to copy unaligned data across kernel/user boundary and currently there is no architecture independent API to do it. (1) Introduce new APIs __{get,put}_user_unaligned. These APIs are necessary because the optimal way to copy unaligned data across kernel/user boundary is different on different architectures. Some architectures don't even care about alignment. On some __put_user is faster than __copy_to_user for small sizes. (2) Optimize __{get,put}_user_unaligned for ia64, x86-64, s390, ppc64. (3) Fix compat_filldir64() which is broken on big-endian machines Thanks to Arnd Bergmann <arnd@arndb.de> for his help. Signed-off-by: Gordon Jin <gordon.jin@intel.com> Signed-off-by: Arun Sharma <arun.sharma@intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/asm-generic')
-rw-r--r--include/asm-generic/uaccess.h26
1 files changed, 26 insertions, 0 deletions
diff --git a/include/asm-generic/uaccess.h b/include/asm-generic/uaccess.h
new file mode 100644
index 000000000000..4d62a1cf543d
--- /dev/null
+++ b/include/asm-generic/uaccess.h
@@ -0,0 +1,26 @@
+#ifndef _ASM_GENERIC_UACCESS_H_
+#define _ASM_GENERIC_UACCESS_H_
+
+/*
+ * This macro should be used instead of __get_user() when accessing
+ * values at locations that are not known to be aligned.
+ */
+#define __get_user_unaligned(x, ptr) \
+({ \
+ __typeof__ (*(ptr)) __x; \
+ __copy_from_user(&__x, (ptr), sizeof(*(ptr))) ? -EFAULT : 0; \
+ (x) = _x; \
+})
+
+
+/*
+ * This macro should be used instead of __put_user() when accessing
+ * values at locations that are not known to be aligned.
+ */
+#define __put_user_unaligned(x, ptr) \
+({ \
+ __typeof__ (*(ptr)) __x = (x); \
+ __copy_to_user((ptr), &__x, sizeof(*(ptr))) ? -EFAULT : 0; \
+})
+
+#endif /* _ASM_GENERIC_UACCESS_H */