]> xenbits.xensource.com Git - xen.git/commitdiff
xen: arm32: ensure cmpxchg has full barrier semantics
authorIan Campbell <ian.campbell@citrix.com>
Wed, 26 Mar 2014 13:38:38 +0000 (13:38 +0000)
committerIan Campbell <ian.campbell@citrix.com>
Thu, 3 Apr 2014 16:15:41 +0000 (17:15 +0100)
Unrelated reads/writes should not pass the xchg.

Provide cmpxchg_local for parity with arm64, although it appears to be unused.
It also helps make the reason for the separation of __cmpxchg_mb more
apparent.

With this our cmpxchg is in sync with Linux v3.14-rc7.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Tim Deegan <tim@xen.org>
xen/include/asm-arm/arm32/system.h

index 9f233fe05b91246ed338c3c536fea4f04a2c90d6..dfaa3b614b436c0f038f84b8a7d4df1bf65d0182 100644 (file)
@@ -113,9 +113,29 @@ static always_inline unsigned long __cmpxchg(
     return oldval;
 }
 
-#define cmpxchg(ptr,o,n)                                                \
-    ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),            \
-                                   (unsigned long)(n),sizeof(*(ptr))))
+static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old,
+                                        unsigned long new, int size)
+{
+       unsigned long ret;
+
+       smp_mb();
+       ret = __cmpxchg(ptr, old, new, size);
+       smp_mb();
+
+       return ret;
+}
+
+#define cmpxchg(ptr,o,n)                                               \
+       ((__typeof__(*(ptr)))__cmpxchg_mb((ptr),                        \
+                                         (unsigned long)(o),           \
+                                         (unsigned long)(n),           \
+                                         sizeof(*(ptr))))
+
+#define cmpxchg_local(ptr,o,n)                                         \
+       ((__typeof__(*(ptr)))__cmpxchg((ptr),                           \
+                                      (unsigned long)(o),              \
+                                      (unsigned long)(n),              \
+                                      sizeof(*(ptr))))
 
 #define local_irq_disable() asm volatile ( "cpsid i @ local_irq_disable\n" : : : "cc" )
 #define local_irq_enable()  asm volatile ( "cpsie i @ local_irq_enable\n" : : : "cc" )