diff mbox

[v3] arm: remove !CPU_V6 and !GENERIC_ATOMIC64 build dependencies for XEN

Message ID 1389204023-26912-1-git-send-email-stefano.stabellini@eu.citrix.com (mailing list archive)
State New, archived
Headers show

Commit Message

Stefano Stabellini Jan. 8, 2014, 6 p.m. UTC
Remove !GENERIC_ATOMIC64 build dependency:
- rename atomic64_xchg to armv7_atomic64_xchg and define it even ifdef
  GENERIC_ATOMIC64;
- call armv7_atomic64_xchg directly from xen/events.h.

Remove !CPU_V6 build dependency:
- introduce __cmpxchg8 and __cmpxchg16, compiled even ifdef
  CONFIG_CPU_V6;
- implement sync_cmpxchg using __cmpxchg8 and __cmpxchg16.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
CC: arnd@arndb.de
CC: linux@arm.linux.org.uk
CC: will.deacon@arm.com
CC: gang.chen@asianux.com
CC: catalin.marinas@arm.com
CC: jaccon.bastiaansen@gmail.com
CC: linux-arm-kernel@lists.infradead.org
CC: linux-kernel@vger.kernel.org


---

Changes in v3:
- rebase.

Changes in v2:
- handle return value of __cmpxchg8 and __cmpxchg16 in __cmpxchg;
- remove sync_cmpxchg to sync_cmpxchg16 rename in grant-table.c,
  implement a generic sync_cmpxchg instead.
---
 arch/arm/Kconfig                   |    3 +-
 arch/arm/include/asm/atomic.h      |   47 +++++++++++++++-------------
 arch/arm/include/asm/cmpxchg.h     |   60 ++++++++++++++++++++++++------------
 arch/arm/include/asm/sync_bitops.h |   24 ++++++++++++++-
 arch/arm/include/asm/xen/events.h  |    2 +-
 5 files changed, 91 insertions(+), 45 deletions(-)

Comments

Will Deacon Jan. 9, 2014, 10:30 a.m. UTC | #1
Hi Stefano,

On Wed, Jan 08, 2014 at 06:00:23PM +0000, Stefano Stabellini wrote:
> Remove !GENERIC_ATOMIC64 build dependency:
> - rename atomic64_xchg to armv7_atomic64_xchg and define it even ifdef
>   GENERIC_ATOMIC64;
> - call armv7_atomic64_xchg directly from xen/events.h.
> 
> Remove !CPU_V6 build dependency:
> - introduce __cmpxchg8 and __cmpxchg16, compiled even ifdef
>   CONFIG_CPU_V6;
> - implement sync_cmpxchg using __cmpxchg8 and __cmpxchg16.
> 
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> CC: arnd@arndb.de
> CC: linux@arm.linux.org.uk
> CC: will.deacon@arm.com
> CC: gang.chen@asianux.com
> CC: catalin.marinas@arm.com
> CC: jaccon.bastiaansen@gmail.com
> CC: linux-arm-kernel@lists.infradead.org
> CC: linux-kernel@vger.kernel.org
> 

I'm confused here. It looks like you want to call armv7 code in a v6 kernel.
What am I missing?

Will
Arnd Bergmann Jan. 9, 2014, 11:04 a.m. UTC | #2
On Thursday 09 January 2014, Will Deacon wrote:
> On Wed, Jan 08, 2014 at 06:00:23PM +0000, Stefano Stabellini wrote:
> > Remove !GENERIC_ATOMIC64 build dependency:
> > - rename atomic64_xchg to armv7_atomic64_xchg and define it even ifdef
> >   GENERIC_ATOMIC64;
> > - call armv7_atomic64_xchg directly from xen/events.h.
> > 
> > Remove !CPU_V6 build dependency:
> > - introduce __cmpxchg8 and __cmpxchg16, compiled even ifdef
> >   CONFIG_CPU_V6;
> > - implement sync_cmpxchg using __cmpxchg8 and __cmpxchg16.
> > 
> > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> > CC: arnd@arndb.de
> > CC: linux@arm.linux.org.uk
> > CC: will.deacon@arm.com
> > CC: gang.chen@asianux.com
> > CC: catalin.marinas@arm.com
> > CC: jaccon.bastiaansen@gmail.com
> > CC: linux-arm-kernel@lists.infradead.org
> > CC: linux-kernel@vger.kernel.org
> > 
> 
> I'm confused here. It looks like you want to call armv7 code in a v6 kernel.
> What am I missing?

This is about being able to build a kernel that runs on ARMv6 and ARMv7
and also includes Xen. Because of obvious hardware limitations, Xen
will only run on v7, but currently you cannot even build it once you
enable (pre-v6K) ARMv6 support, since the combined v6+v7 kernel can't
do atomic accesses in a generic way on non-32bit variables.

	Arnd
Stefano Stabellini Jan. 9, 2014, 12:47 p.m. UTC | #3
On Thu, 9 Jan 2014, Arnd Bergmann wrote:
> On Thursday 09 January 2014, Will Deacon wrote:
> > On Wed, Jan 08, 2014 at 06:00:23PM +0000, Stefano Stabellini wrote:
> > > Remove !GENERIC_ATOMIC64 build dependency:
> > > - rename atomic64_xchg to armv7_atomic64_xchg and define it even ifdef
> > >   GENERIC_ATOMIC64;
> > > - call armv7_atomic64_xchg directly from xen/events.h.
> > > 
> > > Remove !CPU_V6 build dependency:
> > > - introduce __cmpxchg8 and __cmpxchg16, compiled even ifdef
> > >   CONFIG_CPU_V6;
> > > - implement sync_cmpxchg using __cmpxchg8 and __cmpxchg16.
> > > 
> > > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> > > CC: arnd@arndb.de
> > > CC: linux@arm.linux.org.uk
> > > CC: will.deacon@arm.com
> > > CC: gang.chen@asianux.com
> > > CC: catalin.marinas@arm.com
> > > CC: jaccon.bastiaansen@gmail.com
> > > CC: linux-arm-kernel@lists.infradead.org
> > > CC: linux-kernel@vger.kernel.org
> > > 
> > 
> > I'm confused here. It looks like you want to call armv7 code in a v6 kernel.
> > What am I missing?
> 
> This is about being able to build a kernel that runs on ARMv6 and ARMv7
> and also includes Xen. Because of obvious hardware limitations, Xen
> will only run on v7, but currently you cannot even build it once you
> enable (pre-v6K) ARMv6 support, since the combined v6+v7 kernel can't
> do atomic accesses in a generic way on non-32bit variables.

Yep, that's right.
Will Deacon Jan. 9, 2014, 6:42 p.m. UTC | #4
On Thu, Jan 09, 2014 at 12:47:24PM +0000, Stefano Stabellini wrote:
> On Thu, 9 Jan 2014, Arnd Bergmann wrote:
> > On Thursday 09 January 2014, Will Deacon wrote:
> > > On Wed, Jan 08, 2014 at 06:00:23PM +0000, Stefano Stabellini wrote:
> > > > Remove !GENERIC_ATOMIC64 build dependency:
> > > > - rename atomic64_xchg to armv7_atomic64_xchg and define it even ifdef
> > > >   GENERIC_ATOMIC64;
> > > > - call armv7_atomic64_xchg directly from xen/events.h.
> > > > 
> > > > Remove !CPU_V6 build dependency:
> > > > - introduce __cmpxchg8 and __cmpxchg16, compiled even ifdef
> > > >   CONFIG_CPU_V6;
> > > > - implement sync_cmpxchg using __cmpxchg8 and __cmpxchg16.
> > > > 
> > > > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> > > > CC: arnd@arndb.de
> > > > CC: linux@arm.linux.org.uk
> > > > CC: will.deacon@arm.com
> > > > CC: gang.chen@asianux.com
> > > > CC: catalin.marinas@arm.com
> > > > CC: jaccon.bastiaansen@gmail.com
> > > > CC: linux-arm-kernel@lists.infradead.org
> > > > CC: linux-kernel@vger.kernel.org
> > > > 
> > > 
> > > I'm confused here. It looks like you want to call armv7 code in a v6 kernel.
> > > What am I missing?
> > 
> > This is about being able to build a kernel that runs on ARMv6 and ARMv7
> > and also includes Xen. Because of obvious hardware limitations, Xen
> > will only run on v7, but currently you cannot even build it once you
> > enable (pre-v6K) ARMv6 support, since the combined v6+v7 kernel can't
> > do atomic accesses in a generic way on non-32bit variables.
> 
> Yep, that's right.

Ok, thanks for the explanation. Looking at the patch, I wonder whether it's
not cleaner just to implement xchg code separately for Xen? The Linux code
isn't always sufficient (due to the GENERIC_ATOMIC64 stuff) and most of the
churn coming out of this patch is an attempt to provide some small code
reuse at the cost of code readability.

What do others think?

Will
Chen Gang F T Jan. 10, 2014, 4:48 p.m. UTC | #5
On 01/10/2014 02:42 AM, Will Deacon wrote:
> On Thu, Jan 09, 2014 at 12:47:24PM +0000, Stefano Stabellini wrote:
>> On Thu, 9 Jan 2014, Arnd Bergmann wrote:
>>> On Thursday 09 January 2014, Will Deacon wrote:
>>>> On Wed, Jan 08, 2014 at 06:00:23PM +0000, Stefano Stabellini wrote:
>>>>> Remove !GENERIC_ATOMIC64 build dependency:
>>>>> - rename atomic64_xchg to armv7_atomic64_xchg and define it even ifdef
>>>>>   GENERIC_ATOMIC64;
>>>>> - call armv7_atomic64_xchg directly from xen/events.h.
>>>>>
>>>>> Remove !CPU_V6 build dependency:
>>>>> - introduce __cmpxchg8 and __cmpxchg16, compiled even ifdef
>>>>>   CONFIG_CPU_V6;
>>>>> - implement sync_cmpxchg using __cmpxchg8 and __cmpxchg16.
>>>>>
>>>>> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
>>>>> CC: arnd@arndb.de
>>>>> CC: linux@arm.linux.org.uk
>>>>> CC: will.deacon@arm.com
>>>>> CC: gang.chen@asianux.com
>>>>> CC: catalin.marinas@arm.com
>>>>> CC: jaccon.bastiaansen@gmail.com
>>>>> CC: linux-arm-kernel@lists.infradead.org
>>>>> CC: linux-kernel@vger.kernel.org
>>>>>
>>>>
>>>> I'm confused here. It looks like you want to call armv7 code in a v6 kernel.
>>>> What am I missing?
>>>
>>> This is about being able to build a kernel that runs on ARMv6 and ARMv7
>>> and also includes Xen. Because of obvious hardware limitations, Xen
>>> will only run on v7, but currently you cannot even build it once you
>>> enable (pre-v6K) ARMv6 support, since the combined v6+v7 kernel can't
>>> do atomic accesses in a generic way on non-32bit variables.
>>
>> Yep, that's right.
> 
> Ok, thanks for the explanation. Looking at the patch, I wonder whether it's
> not cleaner just to implement xchg code separately for Xen? The Linux code
> isn't always sufficient (due to the GENERIC_ATOMIC64 stuff) and most of the
> churn coming out of this patch is an attempt to provide some small code
> reuse at the cost of code readability.
> 
> What do others think?
> 

What Will said sounds reasonable to me.


Thanks.
Jaccon Bastiaansen Jan. 13, 2014, 8:12 a.m. UTC | #6
2014/1/10 Chen Gang F T <chen.gang.flying.transformer@gmail.com>:
> On 01/10/2014 02:42 AM, Will Deacon wrote:
>> On Thu, Jan 09, 2014 at 12:47:24PM +0000, Stefano Stabellini wrote:
>>> On Thu, 9 Jan 2014, Arnd Bergmann wrote:
>>>> On Thursday 09 January 2014, Will Deacon wrote:
>>>>> On Wed, Jan 08, 2014 at 06:00:23PM +0000, Stefano Stabellini wrote:
>>>>>> Remove !GENERIC_ATOMIC64 build dependency:
>>>>>> - rename atomic64_xchg to armv7_atomic64_xchg and define it even ifdef
>>>>>>   GENERIC_ATOMIC64;
>>>>>> - call armv7_atomic64_xchg directly from xen/events.h.
>>>>>>
>>>>>> Remove !CPU_V6 build dependency:
>>>>>> - introduce __cmpxchg8 and __cmpxchg16, compiled even ifdef
>>>>>>   CONFIG_CPU_V6;
>>>>>> - implement sync_cmpxchg using __cmpxchg8 and __cmpxchg16.
>>>>>>
>>>>>> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
>>>>>> CC: arnd@arndb.de
>>>>>> CC: linux@arm.linux.org.uk
>>>>>> CC: will.deacon@arm.com
>>>>>> CC: gang.chen@asianux.com
>>>>>> CC: catalin.marinas@arm.com
>>>>>> CC: jaccon.bastiaansen@gmail.com
>>>>>> CC: linux-arm-kernel@lists.infradead.org
>>>>>> CC: linux-kernel@vger.kernel.org
>>>>>>
>>>>>
>>>>> I'm confused here. It looks like you want to call armv7 code in a v6 kernel.
>>>>> What am I missing?
>>>>
>>>> This is about being able to build a kernel that runs on ARMv6 and ARMv7
>>>> and also includes Xen. Because of obvious hardware limitations, Xen
>>>> will only run on v7, but currently you cannot even build it once you
>>>> enable (pre-v6K) ARMv6 support, since the combined v6+v7 kernel can't
>>>> do atomic accesses in a generic way on non-32bit variables.
>>>
>>> Yep, that's right.
>>
>> Ok, thanks for the explanation. Looking at the patch, I wonder whether it's
>> not cleaner just to implement xchg code separately for Xen? The Linux code
>> isn't always sufficient (due to the GENERIC_ATOMIC64 stuff) and most of the
>> churn coming out of this patch is an attempt to provide some small code
>> reuse at the cost of code readability.
>>
>> What do others think?
>>
>
> What Will said sounds reasonable to me.
>
>
> Thanks.
> --
> Chen Gang

I agree with Will,

Regards,
  Jaccon
Stefano Stabellini Jan. 16, 2014, 4:27 p.m. UTC | #7
On Thu, 9 Jan 2014, Will Deacon wrote:
> On Thu, Jan 09, 2014 at 12:47:24PM +0000, Stefano Stabellini wrote:
> > On Thu, 9 Jan 2014, Arnd Bergmann wrote:
> > > On Thursday 09 January 2014, Will Deacon wrote:
> > > > On Wed, Jan 08, 2014 at 06:00:23PM +0000, Stefano Stabellini wrote:
> > > > > Remove !GENERIC_ATOMIC64 build dependency:
> > > > > - rename atomic64_xchg to armv7_atomic64_xchg and define it even ifdef
> > > > >   GENERIC_ATOMIC64;
> > > > > - call armv7_atomic64_xchg directly from xen/events.h.
> > > > > 
> > > > > Remove !CPU_V6 build dependency:
> > > > > - introduce __cmpxchg8 and __cmpxchg16, compiled even ifdef
> > > > >   CONFIG_CPU_V6;
> > > > > - implement sync_cmpxchg using __cmpxchg8 and __cmpxchg16.
> > > > > 
> > > > > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> > > > > CC: arnd@arndb.de
> > > > > CC: linux@arm.linux.org.uk
> > > > > CC: will.deacon@arm.com
> > > > > CC: gang.chen@asianux.com
> > > > > CC: catalin.marinas@arm.com
> > > > > CC: jaccon.bastiaansen@gmail.com
> > > > > CC: linux-arm-kernel@lists.infradead.org
> > > > > CC: linux-kernel@vger.kernel.org
> > > > > 
> > > > 
> > > > I'm confused here. It looks like you want to call armv7 code in a v6 kernel.
> > > > What am I missing?
> > > 
> > > This is about being able to build a kernel that runs on ARMv6 and ARMv7
> > > and also includes Xen. Because of obvious hardware limitations, Xen
> > > will only run on v7, but currently you cannot even build it once you
> > > enable (pre-v6K) ARMv6 support, since the combined v6+v7 kernel can't
> > > do atomic accesses in a generic way on non-32bit variables.
> > 
> > Yep, that's right.
> 
> Ok, thanks for the explanation. Looking at the patch, I wonder whether it's
> not cleaner just to implement xchg code separately for Xen? The Linux code
> isn't always sufficient (due to the GENERIC_ATOMIC64 stuff) and most of the
> churn coming out of this patch is an attempt to provide some small code
> reuse at the cost of code readability.
> 
> What do others think?

I am OK with that, in fact my first version of the patch did just that:

http://marc.info/?l=linux-arm-kernel&m=138436406724990&w=2

Is that what you had in mind?
Will Deacon Jan. 16, 2014, 7:31 p.m. UTC | #8
Hi Stefano,

On Thu, Jan 16, 2014 at 04:27:55PM +0000, Stefano Stabellini wrote:
> On Thu, 9 Jan 2014, Will Deacon wrote:
> > Ok, thanks for the explanation. Looking at the patch, I wonder whether it's
> > not cleaner just to implement xchg code separately for Xen? The Linux code
> > isn't always sufficient (due to the GENERIC_ATOMIC64 stuff) and most of the
> > churn coming out of this patch is an attempt to provide some small code
> > reuse at the cost of code readability.
> > 
> > What do others think?
> 
> I am OK with that, in fact my first version of the patch did just that:
> 
> http://marc.info/?l=linux-arm-kernel&m=138436406724990&w=2
> 
> Is that what you had in mind?

For the xchg part, yes, that looks a lot better. I don't like the #undef
CONFIG_CPU_V6 though, can that be rewritten to use __LINUX_ARM_ARCH__?

Will
diff mbox

Patch

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c1f1a7e..ae54ae0 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1881,8 +1881,7 @@  config XEN_DOM0
 config XEN
 	bool "Xen guest support on ARM (EXPERIMENTAL)"
 	depends on ARM && AEABI && OF
-	depends on CPU_V7 && !CPU_V6
-	depends on !GENERIC_ATOMIC64
+	depends on CPU_V7
 	select ARM_PSCI
 	select SWIOTLB_XEN
 	help
diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h
index 62d2cb5..dfe1cd6 100644
--- a/arch/arm/include/asm/atomic.h
+++ b/arch/arm/include/asm/atomic.h
@@ -382,26 +382,7 @@  static inline long long atomic64_cmpxchg(atomic64_t *ptr, long long old,
 	return oldval;
 }
 
-static inline long long atomic64_xchg(atomic64_t *ptr, long long new)
-{
-	long long result;
-	unsigned long tmp;
-
-	smp_mb();
-
-	__asm__ __volatile__("@ atomic64_xchg\n"
-"1:	ldrexd	%0, %H0, [%3]\n"
-"	strexd	%1, %4, %H4, [%3]\n"
-"	teq	%1, #0\n"
-"	bne	1b"
-	: "=&r" (result), "=&r" (tmp), "+Qo" (ptr->counter)
-	: "r" (&ptr->counter), "r" (new)
-	: "cc");
-
-	smp_mb();
-
-	return result;
-}
+#define armv7_atomic64_xchg atomic64_xchg
 
 static inline long long atomic64_dec_if_positive(atomic64_t *v)
 {
@@ -469,6 +450,30 @@  static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
 #define atomic64_dec_and_test(v)	(atomic64_dec_return((v)) == 0)
 #define atomic64_inc_not_zero(v)	atomic64_add_unless((v), 1LL, 0LL)
 
-#endif /* !CONFIG_GENERIC_ATOMIC64 */
+#else /* !CONFIG_GENERIC_ATOMIC64 */
+#include <asm-generic/atomic64.h>
+#endif
+
+static inline u64 armv7_atomic64_xchg(atomic64_t *ptr, u64 new)
+{
+	long long result;
+	unsigned long tmp;
+
+	smp_mb();
+
+	__asm__ __volatile__("@ armv7_atomic64_xchg\n"
+"1:	ldrexd	%0, %H0, [%3]\n"
+"	strexd	%1, %4, %H4, [%3]\n"
+"	teq	%1, #0\n"
+"	bne	1b"
+	: "=&r" (result), "=&r" (tmp), "+Qo" (ptr->counter)
+	: "r" (&ptr->counter), "r" (new)
+	: "cc");
+
+	smp_mb();
+
+	return result;
+}
+
 #endif
 #endif
diff --git a/arch/arm/include/asm/cmpxchg.h b/arch/arm/include/asm/cmpxchg.h
index df2fbba..cc8a4a2 100644
--- a/arch/arm/include/asm/cmpxchg.h
+++ b/arch/arm/include/asm/cmpxchg.h
@@ -133,6 +133,44 @@  extern void __bad_cmpxchg(volatile void *ptr, int size);
  * cmpxchg only support 32-bits operands on ARMv6.
  */
 
+static inline unsigned long __cmpxchg8(volatile void *ptr, unsigned long old,
+				      unsigned long new)
+{
+	unsigned long oldval, res;
+
+	do {
+		asm volatile("@ __cmpxchg1\n"
+		"	ldrexb	%1, [%2]\n"
+		"	mov	%0, #0\n"
+		"	teq	%1, %3\n"
+		"	strexbeq %0, %4, [%2]\n"
+			: "=&r" (res), "=&r" (oldval)
+			: "r" (ptr), "Ir" (old), "r" (new)
+			: "memory", "cc");
+	} while (res);
+
+	return oldval;
+}
+
+static inline unsigned long __cmpxchg16(volatile void *ptr, unsigned long old,
+				      unsigned long new)
+{
+	unsigned long oldval, res;
+
+	do {
+		asm volatile("@ __cmpxchg1\n"
+		"	ldrexh	%1, [%2]\n"
+		"	mov	%0, #0\n"
+		"	teq	%1, %3\n"
+		"	strexheq %0, %4, [%2]\n"
+			: "=&r" (res), "=&r" (oldval)
+			: "r" (ptr), "Ir" (old), "r" (new)
+			: "memory", "cc");
+	} while (res);
+
+	return oldval;
+}
+
 static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
 				      unsigned long new, int size)
 {
@@ -141,28 +179,10 @@  static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
 	switch (size) {
 #ifndef CONFIG_CPU_V6	/* min ARCH >= ARMv6K */
 	case 1:
-		do {
-			asm volatile("@ __cmpxchg1\n"
-			"	ldrexb	%1, [%2]\n"
-			"	mov	%0, #0\n"
-			"	teq	%1, %3\n"
-			"	strexbeq %0, %4, [%2]\n"
-				: "=&r" (res), "=&r" (oldval)
-				: "r" (ptr), "Ir" (old), "r" (new)
-				: "memory", "cc");
-		} while (res);
+		oldval = __cmpxchg8(ptr, old, new);
 		break;
 	case 2:
-		do {
-			asm volatile("@ __cmpxchg1\n"
-			"	ldrexh	%1, [%2]\n"
-			"	mov	%0, #0\n"
-			"	teq	%1, %3\n"
-			"	strexheq %0, %4, [%2]\n"
-				: "=&r" (res), "=&r" (oldval)
-				: "r" (ptr), "Ir" (old), "r" (new)
-				: "memory", "cc");
-		} while (res);
+		oldval = __cmpxchg16(ptr, old, new);
 		break;
 #endif
 	case 4:
diff --git a/arch/arm/include/asm/sync_bitops.h b/arch/arm/include/asm/sync_bitops.h
index 63479ee..942659a 100644
--- a/arch/arm/include/asm/sync_bitops.h
+++ b/arch/arm/include/asm/sync_bitops.h
@@ -21,7 +21,29 @@ 
 #define sync_test_and_clear_bit(nr, p)	_test_and_clear_bit(nr, p)
 #define sync_test_and_change_bit(nr, p)	_test_and_change_bit(nr, p)
 #define sync_test_bit(nr, addr)		test_bit(nr, addr)
-#define sync_cmpxchg			cmpxchg
 
+static inline unsigned long sync_cmpxchg(volatile void *ptr,
+										 unsigned long old,
+										 unsigned long new)
+{
+	unsigned long oldval;
+	int size = sizeof(*(ptr));
+
+	smp_mb();
+	switch (size) {
+	case 1:
+		oldval = __cmpxchg8(ptr, old, new);
+		break;
+	case 2:
+		oldval = __cmpxchg16(ptr, old, new);
+		break;
+	default:
+		oldval = __cmpxchg(ptr, old, new, size);
+		break;
+	}
+	smp_mb();
+
+	return oldval;
+}
 
 #endif
diff --git a/arch/arm/include/asm/xen/events.h b/arch/arm/include/asm/xen/events.h
index 8b1f37b..4269519 100644
--- a/arch/arm/include/asm/xen/events.h
+++ b/arch/arm/include/asm/xen/events.h
@@ -16,7 +16,7 @@  static inline int xen_irqs_disabled(struct pt_regs *regs)
 	return raw_irqs_disabled_flags(regs->ARM_cpsr);
 }
 
-#define xchg_xen_ulong(ptr, val) atomic64_xchg(container_of((ptr),	\
+#define xchg_xen_ulong(ptr, val) armv7_atomic64_xchg(container_of((ptr),	\
 							    atomic64_t,	\
 							    counter), (val))