Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ARM: 9464/1: fix input-only operand modification in load_unaligned_zeropad()

In the inline assembly inside load_unaligned_zeropad(), the "addr" is
constrained as input-only operand. The compiler assumes that on exit
from the asm statement these operands contain the same values as they
had before executing the statement, but when kernel page fault happened, the assembly fixup code "bic %2 %2, #0x3" modify the value of "addr", which may lead to an unexpected behavior.

Use a temporary variable "tmp" to handle it, instead of modifying the
input-only operand, just like what arm64's load_unaligned_zeropad()
does.

Fixes: b9a50f74905a ("ARM: 7450/1: dcache: select DCACHE_WORD_ACCESS for little-endian ARMv6+ CPUs")
Co-developed-by: Xie Yuanbin <xieyuanbin1@huawei.com>
Signed-off-by: Xie Yuanbin <xieyuanbin1@huawei.com>
Signed-off-by: Liyuan Pang <pangliyuan1@huawei.com>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>

authored by

Liyuan Pang and committed by
Russell King (Oracle)
edb924a7 3a866087

+5 -5
+5 -5
arch/arm/include/asm/word-at-a-time.h
··· 67 67 */ 68 68 static inline unsigned long load_unaligned_zeropad(const void *addr) 69 69 { 70 - unsigned long ret, offset; 70 + unsigned long ret, tmp; 71 71 72 72 /* Load word from unaligned pointer addr */ 73 73 asm( ··· 75 75 "2:\n" 76 76 " .pushsection .text.fixup,\"ax\"\n" 77 77 " .align 2\n" 78 - "3: and %1, %2, #0x3\n" 79 - " bic %2, %2, #0x3\n" 80 - " ldr %0, [%2]\n" 78 + "3: bic %1, %2, #0x3\n" 79 + " ldr %0, [%1]\n" 80 + " and %1, %2, #0x3\n" 81 81 " lsl %1, %1, #0x3\n" 82 82 #ifndef __ARMEB__ 83 83 " lsr %0, %0, %1\n" ··· 90 90 " .align 3\n" 91 91 " .long 1b, 3b\n" 92 92 " .popsection" 93 - : "=&r" (ret), "=&r" (offset) 93 + : "=&r" (ret), "=&r" (tmp) 94 94 : "r" (addr), "Qo" (*(unsigned long *)addr)); 95 95 96 96 return ret;