mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86: add cmpxchg16b support
This patch adds cmpxchg16b support for x86-64, so software can perform 128-bit atomic write/read. Signed-off-by: Feng Wu <feng.wu@intel.com> Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
a2b3502c51
commit
e0116acbbd
1 file changed
+33
@@ -5,6 +5,39 @@
|
||||
((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o), \
|
||||
(unsigned long)(n),sizeof(*(ptr))))
|
||||
|
||||
/*
|
||||
* Atomic 16 bytes compare and exchange. Compare OLD with MEM, if
|
||||
* identical, store NEW in MEM. Return the initial value in MEM.
|
||||
* Success is indicated by comparing RETURN with OLD.
|
||||
*
|
||||
* This function can only be called when cpu_has_cx16 is true.
|
||||
*/
|
||||
|
||||
static always_inline __uint128_t __cmpxchg16b(
|
||||
volatile void *ptr, const __uint128_t *old, const __uint128_t *new)
|
||||
{
|
||||
__uint128_t prev;
|
||||
uint64_t new_high = *new >> 64;
|
||||
uint64_t new_low = *new;
|
||||
|
||||
ASSERT(cpu_has_cx16);
|
||||
|
||||
asm volatile ( "lock; cmpxchg16b %1"
|
||||
: "=A" (prev), "+m" (*__xg(ptr))
|
||||
: "c" (new_high), "b" (new_low),
|
||||
"0" (*old) );
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
||||
#define cmpxchg16b(ptr, o, n) ({ \
|
||||
volatile void *_p = (ptr); \
|
||||
ASSERT(!((unsigned long)_p & 0xf)); \
|
||||
BUILD_BUG_ON(sizeof(*(o)) != sizeof(__uint128_t)); \
|
||||
BUILD_BUG_ON(sizeof(*(n)) != sizeof(__uint128_t)); \
|
||||
__cmpxchg16b(_p, (void *)(o), (void *)(n)); \
|
||||
})
|
||||
|
||||
/*
|
||||
* This function causes value _o to be changed to _n at location _p.
|
||||
* If this access causes a fault then we return 1, otherwise we return 0.
|
||||
|
||||