diff options
Diffstat (limited to 'arch/x86/include/asm/cmpxchg_32.h')
-rw-r--r-- | arch/x86/include/asm/cmpxchg_32.h | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/arch/x86/include/asm/cmpxchg_32.h b/arch/x86/include/asm/cmpxchg_32.h index 82ceb788a98..ee1931be659 100644 --- a/arch/x86/include/asm/cmpxchg_32.h +++ b/arch/x86/include/asm/cmpxchg_32.h | |||
@@ -312,19 +312,23 @@ static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old, | |||
312 | 312 | ||
313 | extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64); | 313 | extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64); |
314 | 314 | ||
315 | #define cmpxchg64(ptr, o, n) \ | 315 | #define cmpxchg64(ptr, o, n) \ |
316 | ({ \ | 316 | ({ \ |
317 | __typeof__(*(ptr)) __ret; \ | 317 | __typeof__(*(ptr)) __ret; \ |
318 | if (likely(boot_cpu_data.x86 > 4)) \ | 318 | __typeof__(*(ptr)) __old = (o); \ |
319 | __ret = (__typeof__(*(ptr)))__cmpxchg64((ptr), \ | 319 | __typeof__(*(ptr)) __new = (n); \ |
320 | (unsigned long long)(o), \ | 320 | alternative_io("call cmpxchg8b_emu", \ |
321 | (unsigned long long)(n)); \ | 321 | "lock; cmpxchg8b (%%esi)" , \ |
322 | else \ | 322 | X86_FEATURE_CX8, \ |
323 | __ret = (__typeof__(*(ptr)))cmpxchg_486_u64((ptr), \ | 323 | "=A" (__ret), \ |
324 | (unsigned long long)(o), \ | 324 | "S" ((ptr)), "0" (__old), \ |
325 | (unsigned long long)(n)); \ | 325 | "b" ((unsigned int)__new), \ |
326 | __ret; \ | 326 | "c" ((unsigned int)(__new>>32)) \ |
327 | }) | 327 | : "memory"); \ |
328 | __ret; }) | ||
329 | |||
330 | |||
331 | |||
328 | #define cmpxchg64_local(ptr, o, n) \ | 332 | #define cmpxchg64_local(ptr, o, n) \ |
329 | ({ \ | 333 | ({ \ |
330 | __typeof__(*(ptr)) __ret; \ | 334 | __typeof__(*(ptr)) __ret; \ |