Merge branch 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6.git] / arch / x86 / include / asm / cmpxchg_32.h
index 5371174..ffb9bb6 100644 (file)
@@ -266,19 +266,23 @@ static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old,
 
 extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64);
 
-#define cmpxchg64(ptr, o, n)                                           \
-({                                                                     \
-       __typeof__(*(ptr)) __ret;                                       \
-       if (likely(boot_cpu_data.x86 > 4))                              \
-               __ret = (__typeof__(*(ptr)))__cmpxchg64((ptr),          \
-                               (unsigned long long)(o),                \
-                               (unsigned long long)(n));               \
-       else                                                            \
-               __ret = (__typeof__(*(ptr)))cmpxchg_486_u64((ptr),      \
-                               (unsigned long long)(o),                \
-                               (unsigned long long)(n));               \
-       __ret;                                                          \
-})
+#define cmpxchg64(ptr, o, n)                                   \
+({                                                             \
+       __typeof__(*(ptr)) __ret;                               \
+       __typeof__(*(ptr)) __old = (o);                         \
+       __typeof__(*(ptr)) __new = (n);                         \
+       alternative_io("call cmpxchg8b_emu",                    \
+                       "lock; cmpxchg8b (%%esi)" ,             \
+                      X86_FEATURE_CX8,                         \
+                      "=A" (__ret),                            \
+                      "S" ((ptr)), "0" (__old),                \
+                      "b" ((unsigned int)__new),               \
+                      "c" ((unsigned int)(__new>>32))          \
+                      : "memory");                             \
+       __ret; })
+
+
+
 #define cmpxchg64_local(ptr, o, n)                                     \
 ({                                                                     \
        __typeof__(*(ptr)) __ret;                                       \