diff options
| -rw-r--r-- | arch/x86/include/asm/cmpxchg_32.h | 30 | ||||
| -rw-r--r-- | arch/x86/lib/cmpxchg.c | 18 |
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 | ||
| 249 | extern 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 | } |
| 53 | EXPORT_SYMBOL(cmpxchg_386_u32); | 53 | EXPORT_SYMBOL(cmpxchg_386_u32); |
| 54 | #endif | 54 | #endif |
| 55 | |||
| 56 | #ifndef CONFIG_X86_CMPXCHG64 | ||
| 57 | unsigned 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 | } | ||
| 70 | EXPORT_SYMBOL(cmpxchg_486_u64); | ||
| 71 | #endif | ||
| 72 | |||
