aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/include/asm/atomic_ll_sc.h
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2018-09-13 14:28:33 +0100
committerWill Deacon <will.deacon@arm.com>2018-12-07 17:28:01 +0000
commitb4f9209bfcd5964551de434342818334ab9c8c7e (patch)
tree69578d6a718bb6f9ff0f3f4cad3cecb801a88758 /arch/arm64/include/asm/atomic_ll_sc.h
parentarm64: Avoid redundant type conversions in xchg() and cmpxchg() (diff)
downloadlinux-dev-b4f9209bfcd5964551de434342818334ab9c8c7e.tar.xz
linux-dev-b4f9209bfcd5964551de434342818334ab9c8c7e.zip
arm64: Avoid masking "old" for LSE cmpxchg() implementation
The CAS instructions implicitly access only the relevant bits of the "old" argument, so there is no need for explicit masking via type-casting as there is in the LL/SC implementation. Move the casting into the LL/SC code and remove it altogether for the LSE implementation. Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm64/include/asm/atomic_ll_sc.h')
-rw-r--r--arch/arm64/include/asm/atomic_ll_sc.h8
1 files changed, 8 insertions, 0 deletions
diff --git a/arch/arm64/include/asm/atomic_ll_sc.h b/arch/arm64/include/asm/atomic_ll_sc.h
index f02d3bf7b9e6..b53f70dd6e10 100644
--- a/arch/arm64/include/asm/atomic_ll_sc.h
+++ b/arch/arm64/include/asm/atomic_ll_sc.h
@@ -257,6 +257,14 @@ __LL_SC_PREFIX(__cmpxchg_case_##name##sz(volatile void *ptr, \
unsigned long tmp; \
u##sz oldval; \
\
+ /* \
+ * Sub-word sizes require explicit casting so that the compare \
+ * part of the cmpxchg doesn't end up interpreting non-zero \
+ * upper bits of the register containing "old". \
+ */ \
+ if (sz < 32) \
+ old = (u##sz)old; \
+ \
asm volatile( \
" prfm pstl1strm, %[v]\n" \
"1: ld" #acq "xr" #sfx "\t%" #w "[oldval], %[v]\n" \