1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _ASM_X86_CMPXCHG_32_H
3 #define _ASM_X86_CMPXCHG_32_H
6 * Note: if you use set64_bit(), __cmpxchg64(), or their variants,
7 * you need to test for the feature in boot_cpu_data.
10 #ifdef CONFIG_X86_CMPXCHG64
11 #define arch_cmpxchg64(ptr, o, n) \
12 ((__typeof__(*(ptr)))__cmpxchg64((ptr), (unsigned long long)(o), \
13 (unsigned long long)(n)))
14 #define arch_cmpxchg64_local(ptr, o, n) \
15 ((__typeof__(*(ptr)))__cmpxchg64_local((ptr), (unsigned long long)(o), \
16 (unsigned long long)(n)))
17 #define arch_try_cmpxchg64(ptr, po, n) \
18 __try_cmpxchg64((ptr), (unsigned long long *)(po), \
19 (unsigned long long)(n))
22 static inline u64 __cmpxchg64(volatile u64 *ptr, u64 old, u64 new)
25 asm volatile(LOCK_PREFIX "cmpxchg8b %1"
29 "c" ((u32)(new >> 32)),
35 static inline u64 __cmpxchg64_local(volatile u64 *ptr, u64 old, u64 new)
38 asm volatile("cmpxchg8b %1"
42 "c" ((u32)(new >> 32)),
48 static inline bool __try_cmpxchg64(volatile u64 *ptr, u64 *pold, u64 new)
52 asm volatile(LOCK_PREFIX "cmpxchg8b %[ptr]"
54 : CC_OUT(z) (success),
58 "c" ((u32)(new >> 32))
61 if (unlikely(!success))
66 #ifndef CONFIG_X86_CMPXCHG64
68 * Building a kernel capable running on 80386 and 80486. It may be necessary
69 * to simulate the cmpxchg8b on the 80386 and 80486 CPU.
72 #define arch_cmpxchg64(ptr, o, n) \
74 __typeof__(*(ptr)) __ret; \
75 __typeof__(*(ptr)) __old = (o); \
76 __typeof__(*(ptr)) __new = (n); \
77 alternative_io(LOCK_PREFIX_HERE \
78 "call cmpxchg8b_emu", \
79 "lock; cmpxchg8b (%%esi)" , \
82 "S" ((ptr)), "0" (__old), \
83 "b" ((unsigned int)__new), \
84 "c" ((unsigned int)(__new>>32)) \
89 #define arch_cmpxchg64_local(ptr, o, n) \
91 __typeof__(*(ptr)) __ret; \
92 __typeof__(*(ptr)) __old = (o); \
93 __typeof__(*(ptr)) __new = (n); \
94 alternative_io("call cmpxchg8b_emu", \
95 "cmpxchg8b (%%esi)" , \
98 "S" ((ptr)), "0" (__old), \
99 "b" ((unsigned int)__new), \
100 "c" ((unsigned int)(__new>>32)) \
106 #define system_has_cmpxchg_double() boot_cpu_has(X86_FEATURE_CX8)
108 #endif /* _ASM_X86_CMPXCHG_32_H */