提交 2423de2e 编写于 作者: A Arnd Bergmann 提交者: Russell King (Oracle)

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: NChristoph Hellwig <hch@lst.de>
Reviewed-by: NLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: NArnd Bergmann <arnd@arndb.de>
Signed-off-by: NRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
上级 b30d0289
......@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册