Index: c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S
===================================================================
--- c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S	(revision 4fee1296e96a8c48c29bb6c9340336c67862ed98)
+++ c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S	(revision 5c7bfcf82e1cb46d0a2da486c646eae4146e93c8)
@@ -30,20 +30,20 @@
 #define FRAME_REGISTER r14
 
-#define VECTOR_OFFSET(reg) GPR4_OFFSET(reg)
-#define SELF_CPU_OFFSET(reg) GPR5_OFFSET(reg)
-#define ISR_NEST_OFFSET(reg) GPR6_OFFSET(reg)
-#define DISPATCH_LEVEL_OFFSET(reg) GPR7_OFFSET(reg)
-#define HANDLER_OFFSET(reg) GPR8_OFFSET(reg)
-#define SCRATCH_0_OFFSET(reg) GPR0_OFFSET(reg)
-#define SCRATCH_1_OFFSET(reg) GPR3_OFFSET(reg)
-#define SCRATCH_2_OFFSET(reg) GPR9_OFFSET(reg)
-#define SCRATCH_3_OFFSET(reg) GPR10_OFFSET(reg)
-#define SCRATCH_4_OFFSET(reg) GPR11_OFFSET(reg)
-#define SCRATCH_5_OFFSET(reg) GPR12_OFFSET(reg)
+#define VECTOR_OFFSET GPR4_OFFSET
+#define SELF_CPU_OFFSET GPR5_OFFSET
+#define ISR_NEST_OFFSET GPR6_OFFSET
+#define DISPATCH_LEVEL_OFFSET GPR7_OFFSET
+#define HANDLER_OFFSET GPR8_OFFSET
+#define SCRATCH_0_OFFSET GPR0_OFFSET
+#define SCRATCH_1_OFFSET GPR3_OFFSET
+#define SCRATCH_2_OFFSET GPR9_OFFSET
+#define SCRATCH_3_OFFSET GPR10_OFFSET
+#define SCRATCH_4_OFFSET GPR11_OFFSET
+#define SCRATCH_5_OFFSET GPR12_OFFSET
 
 /*
  * The register 2 slot is free, since this is the read-only small data anchor.
  */
-#define FRAME_OFFSET(reg) GPR2_OFFSET(reg)
+#define FRAME_OFFSET GPR2_OFFSET
 
 #ifdef RTEMS_PROFILING
@@ -52,5 +52,5 @@
  */
 #define ENTRY_INSTANT_REGISTER r15
-#define ENTRY_INSTANT_OFFSET(reg) GPR13_OFFSET(reg)
+#define ENTRY_INSTANT_OFFSET GPR13_OFFSET
 
 .macro GET_TIME_BASE REG
@@ -400,4 +400,29 @@
 #endif
 
+	/*
+	 * We must clear reservations here, since otherwise compare-and-swap
+	 * atomic operations with interrupts enabled may yield wrong results.
+	 * A compare-and-swap atomic operation is generated by the compiler
+	 * like this:
+	 *
+	 *   .L1:
+	 *     lwarx  r9, r0, r3
+	 *     cmpw   r9, r4
+	 *     bne-   .L2
+	 *     stwcx. r5, r0, r3
+	 *     bne-   .L1
+	 *   .L2:
+	 *
+	 * Consider the following scenario.  A thread is interrupted right
+	 * before the stwcx.  The interrupt updates the value using a
+	 * compare-and-swap sequence.  Everything is fine up to this point.
+	 * The interrupt performs now a compare-and-swap sequence which fails
+	 * with a branch to .L2.  The current processor has now a reservation.
+	 * The interrupt returns without further stwcx.  The thread updates the
+	 * value using the unrelated reservation of the interrupt.
+	 */
+	li	SCRATCH_0_REGISTER, FRAME_OFFSET
+	stwcx.	SCRATCH_0_REGISTER, r1, SCRATCH_0_REGISTER
+
 	/* Load SRR0, SRR1, CR, CTR, XER, and LR */
 	lwz	SCRATCH_0_REGISTER, SRR0_FRAME_OFFSET(r1)
Index: cpukit/score/cpu/arm/arm_exc_interrupt.S
===================================================================
--- cpukit/score/cpu/arm/arm_exc_interrupt.S	(revision 4fee1296e96a8c48c29bb6c9340336c67862ed98)
+++ cpukit/score/cpu/arm/arm_exc_interrupt.S	(revision 5c7bfcf82e1cb46d0a2da486c646eae4146e93c8)
@@ -210,4 +210,31 @@
 	ldmia	sp!, {EXCHANGE_LR, EXCHANGE_SPSR}
 
+#ifdef ARM_MULTILIB_HAS_LOAD_STORE_EXCLUSIVE
+	/*
+	 * We must clear reservations here, since otherwise compare-and-swap
+	 * atomic operations with interrupts enabled may yield wrong results.
+	 * A compare-and-swap atomic operation is generated by the compiler
+	 * like this:
+	 *
+	 *   .L1:
+	 *     ldrex r1, [r0]
+	 *     cmp   r1, r3
+	 *     bne   .L2
+	 *     strex r3, r2, [r0]
+	 *     cmp   r3, #0
+	 *     bne   .L1
+	 *   .L2:
+	 *
+	 * Consider the following scenario.  A thread is interrupted right
+	 * before the strex.  The interrupt updates the value using a
+	 * compare-and-swap sequence.  Everything is fine up to this point.
+	 * The interrupt performs now a compare-and-swap sequence which fails
+	 * with a branch to .L2.  The current processor has now a reservation.
+	 * The interrupt returns without further strex.  The thread updates the
+	 * value using the unrelated reservation of the interrupt.
+	 */
+	clrex
+#endif
+
 	/* Return from interrupt */
 	subs	pc, lr, #4
