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 <hch@lst.de> Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
This commit is contained in:
parent
b30d0289de
commit
2423de2e6f
28
mm/maccess.c
28
mm/maccess.c
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue