Merge branch 'misc.namei' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[linux-2.6-microblaze.git] / mm / maccess.c
index 3bd7040..d3f1a1f 100644 (file)
@@ -24,13 +24,21 @@ bool __weak copy_from_kernel_nofault_allowed(const void *unsafe_src,
 
 long copy_from_kernel_nofault(void *dst, const void *src, size_t size)
 {
+       unsigned long align = 0;
+
+       if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS))
+               align = (unsigned long)dst | (unsigned long)src;
+
        if (!copy_from_kernel_nofault_allowed(src, size))
                return -ERANGE;
 
        pagefault_disable();
-       copy_from_kernel_nofault_loop(dst, src, size, u64, Efault);
-       copy_from_kernel_nofault_loop(dst, src, size, u32, Efault);
-       copy_from_kernel_nofault_loop(dst, src, size, u16, Efault);
+       if (!(align & 7))
+               copy_from_kernel_nofault_loop(dst, src, size, u64, Efault);
+       if (!(align & 3))
+               copy_from_kernel_nofault_loop(dst, src, size, u32, Efault);
+       if (!(align & 1))
+               copy_from_kernel_nofault_loop(dst, src, size, u16, Efault);
        copy_from_kernel_nofault_loop(dst, src, size, u8, Efault);
        pagefault_enable();
        return 0;
@@ -50,10 +58,18 @@ EXPORT_SYMBOL_GPL(copy_from_kernel_nofault);
 
 long copy_to_kernel_nofault(void *dst, const void *src, size_t size)
 {
+       unsigned long align = 0;
+
+       if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS))
+               align = (unsigned long)dst | (unsigned long)src;
+
        pagefault_disable();
-       copy_to_kernel_nofault_loop(dst, src, size, u64, Efault);
-       copy_to_kernel_nofault_loop(dst, src, size, u32, Efault);
-       copy_to_kernel_nofault_loop(dst, src, size, u16, Efault);
+       if (!(align & 7))
+               copy_to_kernel_nofault_loop(dst, src, size, u64, Efault);
+       if (!(align & 3))
+               copy_to_kernel_nofault_loop(dst, src, size, u32, Efault);
+       if (!(align & 1))
+               copy_to_kernel_nofault_loop(dst, src, size, u16, Efault);
        copy_to_kernel_nofault_loop(dst, src, size, u8, Efault);
        pagefault_enable();
        return 0;