diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2015-11-11 11:49:45 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2015-11-12 08:21:45 +0100 |
commit | 5c7bfcf82e1cb46d0a2da486c646eae4146e93c8 (patch) | |
tree | 98ec5b445e5402da21af59e2b979fc288d829677 /cpukit | |
parent | Introduce general purpose system server event (diff) | |
download | rtems-5c7bfcf82e1cb46d0a2da486c646eae4146e93c8.tar.bz2 |
Fix interrupt epilogue for ARMv7-AR and PowerPC
Diffstat (limited to 'cpukit')
-rw-r--r-- | cpukit/score/cpu/arm/arm_exc_interrupt.S | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/cpukit/score/cpu/arm/arm_exc_interrupt.S b/cpukit/score/cpu/arm/arm_exc_interrupt.S index 7930c32044..fcb1510b95 100644 --- a/cpukit/score/cpu/arm/arm_exc_interrupt.S +++ b/cpukit/score/cpu/arm/arm_exc_interrupt.S @@ -209,6 +209,33 @@ thread_dispatch_done: /* Restore EXCHANGE_LR and EXCHANGE_SPSR registers from exchange area */ 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 |