Skip to content

Commit edb924a

Browse files
btzdsRussell King (Oracle)
authored andcommitted
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: b9a50f7 ("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>
1 parent 3a86608 commit edb924a

1 file changed

Lines changed: 5 additions & 5 deletions

File tree

arch/arm/include/asm/word-at-a-time.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,17 @@ static inline unsigned long find_zero(unsigned long mask)
6767
*/
6868
static inline unsigned long load_unaligned_zeropad(const void *addr)
6969
{
70-
unsigned long ret, offset;
70+
unsigned long ret, tmp;
7171

7272
/* Load word from unaligned pointer addr */
7373
asm(
7474
"1: ldr %0, [%2]\n"
7575
"2:\n"
7676
" .pushsection .text.fixup,\"ax\"\n"
7777
" .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"
8181
" lsl %1, %1, #0x3\n"
8282
#ifndef __ARMEB__
8383
" lsr %0, %0, %1\n"
@@ -90,7 +90,7 @@ static inline unsigned long load_unaligned_zeropad(const void *addr)
9090
" .align 3\n"
9191
" .long 1b, 3b\n"
9292
" .popsection"
93-
: "=&r" (ret), "=&r" (offset)
93+
: "=&r" (ret), "=&r" (tmp)
9494
: "r" (addr), "Qo" (*(unsigned long *)addr));
9595

9696
return ret;

0 commit comments

Comments
 (0)