dirent = buf->previous;
if (dirent) {
- if (__put_user(offset, (u32 __user *)&dirent->d_off))
- goto efault;
- if (__put_user(offset >> 32,
- ((u32 __user *)&dirent->d_off) + 1))
+ if (__put_user_unaligned(offset, &dirent->d_off))
goto efault;
}
dirent = buf->current_dir;
- if ((__put_user(ino, (u32 __user *)&dirent->d_ino))
- || (__put_user(ino >> 32, ((u32 __user *)&dirent->d_ino) + 1)))
+ if (__put_user_unaligned(ino, &dirent->d_ino))
goto efault;
off = 0;
- if ((__put_user(off, (u32 __user *)&dirent->d_off))
- || (__put_user(off >> 32, ((u32 __user *)&dirent->d_off) + 1)))
+ if (__put_user_unaligned(off, &dirent->d_off))
goto efault;
if (__put_user(reclen, &dirent->d_reclen))
goto efault;
lastdirent = buf.previous;
if (lastdirent) {
typeof(lastdirent->d_off) d_off = file->f_pos;
- __put_user(d_off, (u32 __user *)&lastdirent->d_off);
- __put_user(d_off >> 32, ((u32 __user *)&lastdirent->d_off) + 1);
+ __put_user_unaligned(d_off, &lastdirent->d_off);
error = count - buf.count;
}
--- /dev/null
+#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 */
#define __put_user(x, ptr) __put_user_nocheck((__typeof__(*(ptr))) (x), (ptr), sizeof(*(ptr)))
#define __get_user(x, ptr) __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
+extern long __put_user_unaligned_unknown (void);
+
+#define __put_user_unaligned(x, ptr) \
+({ \
+ long __ret; \
+ switch (sizeof(*(ptr))) { \
+ case 1: __ret = __put_user((x), (ptr)); break; \
+ case 2: __ret = (__put_user((x), (u8 __user *)(ptr))) \
+ | (__put_user((x) >> 8, ((u8 __user *)(ptr) + 1))); break; \
+ case 4: __ret = (__put_user((x), (u16 __user *)(ptr))) \
+ | (__put_user((x) >> 16, ((u16 __user *)(ptr) + 1))); break; \
+ case 8: __ret = (__put_user((x), (u32 __user *)(ptr))) \
+ | (__put_user((x) >> 32, ((u32 __user *)(ptr) + 1))); break; \
+ default: __ret = __put_user_unaligned_unknown(); \
+ } \
+ __ret; \
+})
+
+extern long __get_user_unaligned_unknown (void);
+
+#define __get_user_unaligned(x, ptr) \
+({ \
+ long __ret; \
+ switch (sizeof(*(ptr))) { \
+ case 1: __ret = __get_user((x), (ptr)); break; \
+ case 2: __ret = (__get_user((x), (u8 __user *)(ptr))) \
+ | (__get_user((x) >> 8, ((u8 __user *)(ptr) + 1))); break; \
+ case 4: __ret = (__get_user((x), (u16 __user *)(ptr))) \
+ | (__get_user((x) >> 16, ((u16 __user *)(ptr) + 1))); break; \
+ case 8: __ret = (__get_user((x), (u32 __user *)(ptr))) \
+ | (__get_user((x) >> 32, ((u32 __user *)(ptr) + 1))); break; \
+ default: __ret = __get_user_unaligned_unknown(); \
+ } \
+ __ret; \
+})
+
#ifdef ASM_SUPPORTED
struct __large_struct { unsigned long buf[100]; };
# define __m(x) (*(struct __large_struct *)(x))
#include <linux/compiler.h>
#include <linux/errno.h>
#include <linux/thread_info.h>
+#include <asm-generic/uaccess.h>
/*
* The fs value determines whether argument validity checking should be
#define __put_user(x,ptr) \
__put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+#define __get_user_unaligned __get_user
+#define __put_user_unaligned __put_user
+
extern long __put_user_bad(void);
#define __put_user_nocheck(x,ptr,size) \
extern int __get_user_bad(void);
+#define __put_user_unaligned __put_user
+#define __get_user_unaligned __get_user
+
extern long __copy_to_user_asm(const void *from, long n, void __user *to);
/**
#include <asm/asi.h>
#include <asm/system.h>
#include <asm/spitfire.h>
+#include <asm-generic/uaccess.h>
#endif
#ifndef __ASSEMBLY__
#define __put_user(x,ptr) \
__put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+#define __get_user_unaligned __get_user
+#define __put_user_unaligned __put_user
+
#define __put_user_nocheck(x,ptr,size) \
({ \
int __pu_err; \