From: Peter Collingbourne <p...@google.com>

commit 185f2e5f51c2029efd9dd26cceb968a44fe053c6 upstream.

The inline asm's addr operand is marked as input-only, however in
the case where an exception is taken it may be modified by the BIC
instruction on the exception path. Fix the problem by using a temporary
register as the destination register for the BIC instruction.

Signed-off-by: Peter Collingbourne <p...@google.com>
Cc: sta...@vger.kernel.org
Link: 
https://linux-review.googlesource.com/id/I84538c8a2307d567b4f45bb20b715451005f9617
Link: https://lore.kernel.org/r/20210401165110.3952103-1-...@google.com
Signed-off-by: Will Deacon <w...@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
 arch/arm64/include/asm/word-at-a-time.h |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

--- a/arch/arm64/include/asm/word-at-a-time.h
+++ b/arch/arm64/include/asm/word-at-a-time.h
@@ -53,7 +53,7 @@ static inline unsigned long find_zero(un
  */
 static inline unsigned long load_unaligned_zeropad(const void *addr)
 {
-       unsigned long ret, offset;
+       unsigned long ret, tmp;
 
        /* Load word from unaligned pointer addr */
        asm(
@@ -61,9 +61,9 @@ static inline unsigned long load_unalign
        "2:\n"
        "       .pushsection .fixup,\"ax\"\n"
        "       .align 2\n"
-       "3:     and     %1, %2, #0x7\n"
-       "       bic     %2, %2, #0x7\n"
-       "       ldr     %0, [%2]\n"
+       "3:     bic     %1, %2, #0x7\n"
+       "       ldr     %0, [%1]\n"
+       "       and     %1, %2, #0x7\n"
        "       lsl     %1, %1, #0x3\n"
 #ifndef __AARCH64EB__
        "       lsr     %0, %0, %1\n"
@@ -73,7 +73,7 @@ static inline unsigned long load_unalign
        "       b       2b\n"
        "       .popsection\n"
        _ASM_EXTABLE(1b, 3b)
-       : "=&r" (ret), "=&r" (offset)
+       : "=&r" (ret), "=&r" (tmp)
        : "r" (addr), "Q" (*(unsigned long *)addr));
 
        return ret;


Reply via email to