Commit 185f2e5f authored by Peter Collingbourne's avatar Peter Collingbourne Committed by Will Deacon

arm64: fix inline asm in load_unaligned_zeropad()

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: default avatarPeter Collingbourne <pcc@google.com>
Cc: stable@vger.kernel.org
Link: https://linux-review.googlesource.com/id/I84538c8a2307d567b4f45bb20b715451005f9617
Link: https://lore.kernel.org/r/20210401165110.3952103-1-pcc@google.comSigned-off-by: default avatarWill Deacon <will@kernel.org>
parent 20109a85
...@@ -53,7 +53,7 @@ static inline unsigned long find_zero(unsigned long mask) ...@@ -53,7 +53,7 @@ static inline unsigned long find_zero(unsigned long mask)
*/ */
static inline unsigned long load_unaligned_zeropad(const void *addr) static inline unsigned long load_unaligned_zeropad(const void *addr)
{ {
unsigned long ret, offset; unsigned long ret, tmp;
/* Load word from unaligned pointer addr */ /* Load word from unaligned pointer addr */
asm( asm(
...@@ -61,9 +61,9 @@ static inline unsigned long load_unaligned_zeropad(const void *addr) ...@@ -61,9 +61,9 @@ static inline unsigned long load_unaligned_zeropad(const void *addr)
"2:\n" "2:\n"
" .pushsection .fixup,\"ax\"\n" " .pushsection .fixup,\"ax\"\n"
" .align 2\n" " .align 2\n"
"3: and %1, %2, #0x7\n" "3: bic %1, %2, #0x7\n"
" bic %2, %2, #0x7\n" " ldr %0, [%1]\n"
" ldr %0, [%2]\n" " and %1, %2, #0x7\n"
" lsl %1, %1, #0x3\n" " lsl %1, %1, #0x3\n"
#ifndef __AARCH64EB__ #ifndef __AARCH64EB__
" lsr %0, %0, %1\n" " lsr %0, %0, %1\n"
...@@ -73,7 +73,7 @@ static inline unsigned long load_unaligned_zeropad(const void *addr) ...@@ -73,7 +73,7 @@ static inline unsigned long load_unaligned_zeropad(const void *addr)
" b 2b\n" " b 2b\n"
" .popsection\n" " .popsection\n"
_ASM_EXTABLE(1b, 3b) _ASM_EXTABLE(1b, 3b)
: "=&r" (ret), "=&r" (offset) : "=&r" (ret), "=&r" (tmp)
: "r" (addr), "Q" (*(unsigned long *)addr)); : "r" (addr), "Q" (*(unsigned long *)addr));
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment