Skip to content

Commit bba445b

Browse files
Andrew BoieAnas Nashif
authored andcommitted
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 15bc537 for the ARM fix for a complete description of the issue and fix. Change-Id: I1d96fe0088d90150f0888c2893d017155fc0a0a7 Signed-off-by: Andrew Boie <[email protected]>
1 parent 0e2451e commit bba445b

File tree

1 file changed

+21
-14
lines changed

1 file changed

+21
-14
lines changed

include/arch/nios2/arch.h

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,15 @@ typedef unsigned int vaddr_t;
9494

9595
static ALWAYS_INLINE unsigned int _arch_irq_lock(void)
9696
{
97-
unsigned int key;
97+
unsigned int key, tmp;
9898

99-
key = _nios2_creg_read(NIOS2_CR_STATUS);
100-
_nios2_creg_write(NIOS2_CR_STATUS, key & ~NIOS2_STATUS_PIE_MSK);
99+
__asm__ volatile (
100+
"rdctl %[key], status\n\t"
101+
"movi %[tmp], -2\n\t"
102+
"and %[tmp], %[key], %[tmp]\n\t"
103+
"wrctl status, %[tmp]\n\t"
104+
: [key] "=r" (key), [tmp] "=r" (tmp)
105+
: : "memory");
101106

102107
return key;
103108
}
@@ -117,18 +122,20 @@ static ALWAYS_INLINE void _arch_irq_unlock(unsigned int key)
117122
(defined ALT_CPU_EIC_PRESENT) || \
118123
(defined ALT_CPU_MMU_PRESENT) || \
119124
(defined ALT_CPU_MPU_PRESENT)
120-
uint32_t status_reg;
121-
122-
/* Interrupts were already locked when irq_lock() was called,
123-
* so don't do anything
124-
*/
125-
if (!(key & NIOS2_STATUS_PIE_MSK))
126-
return;
127-
128-
status_reg = _nios2_creg_read(NIOS2_CR_STATUS);
129-
_nios2_creg_write(NIOS2_CR_STATUS, status_reg | NIOS2_STATUS_PIE_MSK);
125+
__asm__ volatile (
126+
"andi %[key], %[key], 1\n\t"
127+
"beq %[key], zero, 1f\n\t"
128+
"rdctl %[key], status\n\t"
129+
"ori %[key], %[key], 1\n\t"
130+
"wrctl status, %[key]\n\t"
131+
"1:\n\t"
132+
: [key] "+r" (key)
133+
: : "memory");
130134
#else
131-
_nios2_creg_write(NIOS2_CR_STATUS, key);
135+
__asm__ volatile (
136+
"wrctl status, %[key]"
137+
: : [key] "r" (key)
138+
: "memory");
132139
#endif
133140
}
134141

0 commit comments

Comments
 (0)