| From 185f2e5f51c2029efd9dd26cceb968a44fe053c6 Mon Sep 17 00:00:00 2001 |
| From: Peter Collingbourne <pcc@google.com> |
| Date: Thu, 1 Apr 2021 09:51:10 -0700 |
| Subject: arm64: fix inline asm in load_unaligned_zeropad() |
| |
| From: Peter Collingbourne <pcc@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 <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.com |
| Signed-off-by: Will Deacon <will@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@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; |