diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2008-06-25 00:19:10 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-08 07:10:58 -0400 |
commit | 15878c0b21b7b04a08108e9027ebbbd68a2502e0 (patch) | |
tree | 8f353123bdf455547807b0dec347e8d0618b4b6b | |
parent | 102e3b8d3f3d5556c60f9ab6d92108649b68edc8 (diff) |
x86, 64-bit: add sync_cmpxchg
Add sync_cmpxchg to match 32-bit's sync_cmpxchg.
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Cc: xen-devel <xen-devel@lists.xensource.com>
Cc: Stephen Tweedie <sct@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Mark McLoughlin <markmc@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | include/asm-x86/cmpxchg_64.h | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/include/asm-x86/cmpxchg_64.h b/include/asm-x86/cmpxchg_64.h index d9b26b9a28cf..17463ccf8166 100644 --- a/include/asm-x86/cmpxchg_64.h +++ b/include/asm-x86/cmpxchg_64.h | |||
@@ -93,6 +93,39 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, | |||
93 | return old; | 93 | return old; |
94 | } | 94 | } |
95 | 95 | ||
96 | /* | ||
97 | * Always use locked operations when touching memory shared with a | ||
98 | * hypervisor, since the system may be SMP even if the guest kernel | ||
99 | * isn't. | ||
100 | */ | ||
101 | static inline unsigned long __sync_cmpxchg(volatile void *ptr, | ||
102 | unsigned long old, | ||
103 | unsigned long new, int size) | ||
104 | { | ||
105 | unsigned long prev; | ||
106 | switch (size) { | ||
107 | case 1: | ||
108 | asm volatile("lock; cmpxchgb %b1,%2" | ||
109 | : "=a"(prev) | ||
110 | : "q"(new), "m"(*__xg(ptr)), "0"(old) | ||
111 | : "memory"); | ||
112 | return prev; | ||
113 | case 2: | ||
114 | asm volatile("lock; cmpxchgw %w1,%2" | ||
115 | : "=a"(prev) | ||
116 | : "r"(new), "m"(*__xg(ptr)), "0"(old) | ||
117 | : "memory"); | ||
118 | return prev; | ||
119 | case 4: | ||
120 | asm volatile("lock; cmpxchgl %1,%2" | ||
121 | : "=a"(prev) | ||
122 | : "r"(new), "m"(*__xg(ptr)), "0"(old) | ||
123 | : "memory"); | ||
124 | return prev; | ||
125 | } | ||
126 | return old; | ||
127 | } | ||
128 | |||
96 | static inline unsigned long __cmpxchg_local(volatile void *ptr, | 129 | static inline unsigned long __cmpxchg_local(volatile void *ptr, |
97 | unsigned long old, | 130 | unsigned long old, |
98 | unsigned long new, int size) | 131 | unsigned long new, int size) |
@@ -139,6 +172,10 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr, | |||
139 | ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \ | 172 | ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \ |
140 | (unsigned long)(n), \ | 173 | (unsigned long)(n), \ |
141 | sizeof(*(ptr)))) | 174 | sizeof(*(ptr)))) |
175 | #define sync_cmpxchg(ptr, o, n) \ | ||
176 | ((__typeof__(*(ptr)))__sync_cmpxchg((ptr), (unsigned long)(o), \ | ||
177 | (unsigned long)(n), \ | ||
178 | sizeof(*(ptr)))) | ||
142 | #define cmpxchg64_local(ptr, o, n) \ | 179 | #define cmpxchg64_local(ptr, o, n) \ |
143 | ({ \ | 180 | ({ \ |
144 | BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ | 181 | BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ |