Skip to content

Commit 2423de2

Browse files
arndbRussell King (Oracle)
authored andcommitted
ARM: 9115/1: mm/maccess: fix unaligned copy_{from,to}_kernel_nofault
On machines such as ARMv5 that trap unaligned accesses, these two functions can be slow when each access needs to be emulated, or they might not work at all. Change them so that each loop is only used when both the src and dst pointers are naturally aligned. Reviewed-by: Christoph Hellwig <[email protected]> Reviewed-by: Linus Walleij <[email protected]> Signed-off-by: Arnd Bergmann <[email protected]> Signed-off-by: Russell King (Oracle) <[email protected]>
1 parent b30d028 commit 2423de2

File tree

1 file changed

+22
-6
lines changed

1 file changed

+22
-6
lines changed

mm/maccess.c

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,21 @@ bool __weak copy_from_kernel_nofault_allowed(const void *unsafe_src,
2424

2525
long copy_from_kernel_nofault(void *dst, const void *src, size_t size)
2626
{
27+
unsigned long align = 0;
28+
29+
if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS))
30+
align = (unsigned long)dst | (unsigned long)src;
31+
2732
if (!copy_from_kernel_nofault_allowed(src, size))
2833
return -ERANGE;
2934

3035
pagefault_disable();
31-
copy_from_kernel_nofault_loop(dst, src, size, u64, Efault);
32-
copy_from_kernel_nofault_loop(dst, src, size, u32, Efault);
33-
copy_from_kernel_nofault_loop(dst, src, size, u16, Efault);
36+
if (!(align & 7))
37+
copy_from_kernel_nofault_loop(dst, src, size, u64, Efault);
38+
if (!(align & 3))
39+
copy_from_kernel_nofault_loop(dst, src, size, u32, Efault);
40+
if (!(align & 1))
41+
copy_from_kernel_nofault_loop(dst, src, size, u16, Efault);
3442
copy_from_kernel_nofault_loop(dst, src, size, u8, Efault);
3543
pagefault_enable();
3644
return 0;
@@ -50,10 +58,18 @@ EXPORT_SYMBOL_GPL(copy_from_kernel_nofault);
5058

5159
long copy_to_kernel_nofault(void *dst, const void *src, size_t size)
5260
{
61+
unsigned long align = 0;
62+
63+
if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS))
64+
align = (unsigned long)dst | (unsigned long)src;
65+
5366
pagefault_disable();
54-
copy_to_kernel_nofault_loop(dst, src, size, u64, Efault);
55-
copy_to_kernel_nofault_loop(dst, src, size, u32, Efault);
56-
copy_to_kernel_nofault_loop(dst, src, size, u16, Efault);
67+
if (!(align & 7))
68+
copy_to_kernel_nofault_loop(dst, src, size, u64, Efault);
69+
if (!(align & 3))
70+
copy_to_kernel_nofault_loop(dst, src, size, u32, Efault);
71+
if (!(align & 1))
72+
copy_to_kernel_nofault_loop(dst, src, size, u16, Efault);
5773
copy_to_kernel_nofault_loop(dst, src, size, u8, Efault);
5874
pagefault_enable();
5975
return 0;

0 commit comments

Comments
 (0)