aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2010-07-28 20:05:11 -0400
committerH. Peter Anvin <hpa@linux.intel.com>2010-07-28 20:05:11 -0400
commita378d9338e8dde78314b3a6ae003de351936c729 (patch)
tree1f0c947c4c55bbb98c129a260ac604f6b39526ac /arch
parent90c8f92f5c807807ca74d5f2f313794925174e6b (diff)
x86, asm: Merge cmpxchg_486_u64() and cmpxchg8b_emu()
We have two functions for doing exactly the same thing -- emulating cmpxchg8b on 486 and older hardware -- with different calling conventions, and yet doing the same thing. Drop the C version and use the assembly version, via alternatives, for both the local and non-local versions of cmpxchg8b. Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> LKML-Reference: <AANLkTikAmaDPji-TVDarmG1yD=fwbffcsmEU=YEuP+8r@mail.gmail.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/include/asm/cmpxchg_32.h30
-rw-r--r--arch/x86/lib/cmpxchg.c18
2 files changed, 14 insertions, 34 deletions
diff --git a/arch/x86/include/asm/cmpxchg_32.h b/arch/x86/include/asm/cmpxchg_32.h
index f5bd1fd388ff..284a6e8f7ce1 100644
--- a/arch/x86/include/asm/cmpxchg_32.h
+++ b/arch/x86/include/asm/cmpxchg_32.h
@@ -246,8 +246,6 @@ static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old,
246 * to simulate the cmpxchg8b on the 80386 and 80486 CPU. 246 * to simulate the cmpxchg8b on the 80386 and 80486 CPU.
247 */ 247 */
248 248
249extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64);
250
251#define cmpxchg64(ptr, o, n) \ 249#define cmpxchg64(ptr, o, n) \
252({ \ 250({ \
253 __typeof__(*(ptr)) __ret; \ 251 __typeof__(*(ptr)) __ret; \
@@ -265,20 +263,20 @@ extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64);
265 __ret; }) 263 __ret; })
266 264
267 265
268 266#define cmpxchg64_local(ptr, o, n) \
269#define cmpxchg64_local(ptr, o, n) \ 267({ \
270({ \ 268 __typeof__(*(ptr)) __ret; \
271 __typeof__(*(ptr)) __ret; \ 269 __typeof__(*(ptr)) __old = (o); \
272 if (likely(boot_cpu_data.x86 > 4)) \ 270 __typeof__(*(ptr)) __new = (n); \
273 __ret = (__typeof__(*(ptr)))__cmpxchg64_local((ptr), \ 271 alternative_io("call cmpxchg8b_emu", \
274 (unsigned long long)(o), \ 272 "cmpxchg8b (%%esi)" , \
275 (unsigned long long)(n)); \ 273 X86_FEATURE_CX8, \
276 else \ 274 "=A" (__ret), \
277 __ret = (__typeof__(*(ptr)))cmpxchg_486_u64((ptr), \ 275 "S" ((ptr)), "0" (__old), \
278 (unsigned long long)(o), \ 276 "b" ((unsigned int)__new), \
279 (unsigned long long)(n)); \ 277 "c" ((unsigned int)(__new>>32)) \
280 __ret; \ 278 : "memory"); \
281}) 279 __ret; })
282 280
283#endif 281#endif
284 282
diff --git a/arch/x86/lib/cmpxchg.c b/arch/x86/lib/cmpxchg.c
index 2056ccf572cc..5d619f6df3ee 100644
--- a/arch/x86/lib/cmpxchg.c
+++ b/arch/x86/lib/cmpxchg.c
@@ -52,21 +52,3 @@ unsigned long cmpxchg_386_u32(volatile void *ptr, u32 old, u32 new)
52} 52}
53EXPORT_SYMBOL(cmpxchg_386_u32); 53EXPORT_SYMBOL(cmpxchg_386_u32);
54#endif 54#endif
55
56#ifndef CONFIG_X86_CMPXCHG64
57unsigned long long cmpxchg_486_u64(volatile void *ptr, u64 old, u64 new)
58{
59 u64 prev;
60 unsigned long flags;
61
62 /* Poor man's cmpxchg8b for 386 and 486. Unsuitable for SMP */
63 local_irq_save(flags);
64 prev = *(u64 *)ptr;
65 if (prev == old)
66 *(u64 *)ptr = new;
67 local_irq_restore(flags);
68 return prev;
69}
70EXPORT_SYMBOL(cmpxchg_486_u64);
71#endif
72