nios2: fix irq_lock/unlock ordering bug
Memory accesses could be reordered before an irq_lock() or
after an irq_unlock() without the memory barriers.
See commit 15bc537712
for the
ARM fix for a complete description of the issue and fix.
Change-Id: I1d96fe0088d90150f0888c2893d017155fc0a0a7
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
0e2451e3a0
commit
bba445b31f
1 changed files with 21 additions and 14 deletions
|
@ -94,10 +94,15 @@ typedef unsigned int vaddr_t;
|
||||||
|
|
||||||
static ALWAYS_INLINE unsigned int _arch_irq_lock(void)
|
static ALWAYS_INLINE unsigned int _arch_irq_lock(void)
|
||||||
{
|
{
|
||||||
unsigned int key;
|
unsigned int key, tmp;
|
||||||
|
|
||||||
key = _nios2_creg_read(NIOS2_CR_STATUS);
|
__asm__ volatile (
|
||||||
_nios2_creg_write(NIOS2_CR_STATUS, key & ~NIOS2_STATUS_PIE_MSK);
|
"rdctl %[key], status\n\t"
|
||||||
|
"movi %[tmp], -2\n\t"
|
||||||
|
"and %[tmp], %[key], %[tmp]\n\t"
|
||||||
|
"wrctl status, %[tmp]\n\t"
|
||||||
|
: [key] "=r" (key), [tmp] "=r" (tmp)
|
||||||
|
: : "memory");
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
@ -117,18 +122,20 @@ static ALWAYS_INLINE void _arch_irq_unlock(unsigned int key)
|
||||||
(defined ALT_CPU_EIC_PRESENT) || \
|
(defined ALT_CPU_EIC_PRESENT) || \
|
||||||
(defined ALT_CPU_MMU_PRESENT) || \
|
(defined ALT_CPU_MMU_PRESENT) || \
|
||||||
(defined ALT_CPU_MPU_PRESENT)
|
(defined ALT_CPU_MPU_PRESENT)
|
||||||
uint32_t status_reg;
|
__asm__ volatile (
|
||||||
|
"andi %[key], %[key], 1\n\t"
|
||||||
/* Interrupts were already locked when irq_lock() was called,
|
"beq %[key], zero, 1f\n\t"
|
||||||
* so don't do anything
|
"rdctl %[key], status\n\t"
|
||||||
*/
|
"ori %[key], %[key], 1\n\t"
|
||||||
if (!(key & NIOS2_STATUS_PIE_MSK))
|
"wrctl status, %[key]\n\t"
|
||||||
return;
|
"1:\n\t"
|
||||||
|
: [key] "+r" (key)
|
||||||
status_reg = _nios2_creg_read(NIOS2_CR_STATUS);
|
: : "memory");
|
||||||
_nios2_creg_write(NIOS2_CR_STATUS, status_reg | NIOS2_STATUS_PIE_MSK);
|
|
||||||
#else
|
#else
|
||||||
_nios2_creg_write(NIOS2_CR_STATUS, key);
|
__asm__ volatile (
|
||||||
|
"wrctl status, %[key]"
|
||||||
|
: : [key] "r" (key)
|
||||||
|
: "memory");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue