提交 a378d933 编写于 作者: H H. Peter Anvin

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: NH. Peter Anvin <hpa@linux.intel.com>
LKML-Reference: <AANLkTikAmaDPji-TVDarmG1yD=fwbffcsmEU=YEuP+8r@mail.gmail.com>
上级 90c8f92f
...@@ -246,8 +246,6 @@ static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old, ...@@ -246,8 +246,6 @@ static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old,
* to simulate the cmpxchg8b on the 80386 and 80486 CPU. * to simulate the cmpxchg8b on the 80386 and 80486 CPU.
*/ */
extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64);
#define cmpxchg64(ptr, o, n) \ #define cmpxchg64(ptr, o, n) \
({ \ ({ \
__typeof__(*(ptr)) __ret; \ __typeof__(*(ptr)) __ret; \
...@@ -265,20 +263,20 @@ extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64); ...@@ -265,20 +263,20 @@ extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64);
__ret; }) __ret; })
#define cmpxchg64_local(ptr, o, n) \ #define cmpxchg64_local(ptr, o, n) \
({ \ ({ \
__typeof__(*(ptr)) __ret; \ __typeof__(*(ptr)) __ret; \
if (likely(boot_cpu_data.x86 > 4)) \ __typeof__(*(ptr)) __old = (o); \
__ret = (__typeof__(*(ptr)))__cmpxchg64_local((ptr), \ __typeof__(*(ptr)) __new = (n); \
(unsigned long long)(o), \ alternative_io("call cmpxchg8b_emu", \
(unsigned long long)(n)); \ "cmpxchg8b (%%esi)" , \
else \ X86_FEATURE_CX8, \
__ret = (__typeof__(*(ptr)))cmpxchg_486_u64((ptr), \ "=A" (__ret), \
(unsigned long long)(o), \ "S" ((ptr)), "0" (__old), \
(unsigned long long)(n)); \ "b" ((unsigned int)__new), \
__ret; \ "c" ((unsigned int)(__new>>32)) \
}) : "memory"); \
__ret; })
#endif #endif
......
...@@ -52,21 +52,3 @@ unsigned long cmpxchg_386_u32(volatile void *ptr, u32 old, u32 new) ...@@ -52,21 +52,3 @@ unsigned long cmpxchg_386_u32(volatile void *ptr, u32 old, u32 new)
} }
EXPORT_SYMBOL(cmpxchg_386_u32); EXPORT_SYMBOL(cmpxchg_386_u32);
#endif #endif
#ifndef CONFIG_X86_CMPXCHG64
unsigned long long cmpxchg_486_u64(volatile void *ptr, u64 old, u64 new)
{
u64 prev;
unsigned long flags;
/* Poor man's cmpxchg8b for 386 and 486. Unsuitable for SMP */
local_irq_save(flags);
prev = *(u64 *)ptr;
if (prev == old)
*(u64 *)ptr = new;
local_irq_restore(flags);
return prev;
}
EXPORT_SYMBOL(cmpxchg_486_u64);
#endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册