Skip to content

Commit 2c577ff

Browse files
Wayne Renruuddw
authored andcommitted
arch: arc: fix the bug of context switch in interrupt
* the bug comes out when a context switch happens in interrupt * the bug only affects the em7d in emsk 2.3 * the bug is caused by * wrong operations of stack * wrong setting of SEC_STAT's IRM bit Signed-off-by: Wayne Ren <[email protected]>
1 parent 6612c9f commit 2c577ff

File tree

2 files changed

+24
-30
lines changed

2 files changed

+24
-30
lines changed

arch/arc/core/regular_irq.S

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -180,44 +180,27 @@ _rirq_common_interrupt_swap:
180180
.balign 4
181181
_rirq_return_from_coop:
182182

183-
/* status32 and pc (blink) are already on the stack in the right order */
183+
/*
184+
* status32, sec_stat (when CONFIG_ARC_HAS_SECURE is enabled) and pc
185+
* (blink) are already on the stack in the right order
186+
*/
187+
ld_s r0, [sp, ___isf_t_status32_OFFSET - ___isf_t_pc_OFFSET]
184188

185189
/* update status32.ie (explanation in firq_exit:_firq_return_from_coop) */
186-
ld_s r0, [sp, 4]
190+
187191
ld_s r3, [r2, _thread_offset_to_intlock_key]
188192
st 0, [r2, _thread_offset_to_intlock_key]
189193
cmp r3, 0
190194
or.ne r0, r0, _ARC_V2_STATUS32_IE
191-
st_s r0, [sp, 4]
195+
196+
st_s r0, [sp, ___isf_t_status32_OFFSET - ___isf_t_pc_OFFSET]
192197

193198
/* carve fake stack */
199+
sub sp, sp, ___isf_t_pc_OFFSET
194200

195-
#ifdef CONFIG_ARC_HAS_SECURE
196-
/* a) status32/pc are already on the stack
197-
* pc
198-
* status
199-
* b) make a space for sec_stat
200-
* c) adjust the right place for sec_stat and pc
201-
* pc
202-
* sec_stat
203-
* status
204-
* d) a real value will be pushed in r0
205-
*/
206-
ld_s r0, [sp]
207-
push_s r0
208-
lr r0, [_ARC_V2_SEC_STAT]
209-
st_s r0, [sp, 4]
210-
sub sp, sp, (___isf_t_SIZEOF - 16)
211-
#else
212-
/*
213-
* a) status32/pc are already on the stack
214-
* b) a real value will be pushed in r0
215-
*/
216-
sub sp, sp, (___isf_t_SIZEOF - 12)
217-
#endif
218-
/* push return value on stack */
201+
/* update return value on stack */
219202
ld_s r0, [r2, _thread_offset_to_return_value]
220-
push_s r0
203+
st_s r0, [sp, ___isf_t_r0_OFFSET]
221204

222205
/*
223206
* r13 is part of both the callee and caller-saved register sets because

arch/arc/core/swap.S

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,21 @@ _swap_return_from_firq:
163163
bbit1 r3, _ARC_V2_STATUS32_AE_BIT, _return_from_exc_irq
164164

165165
/* pretend interrupt happened to use rtie instruction */
166+
167+
#ifdef CONFIG_ARC_HAS_SECURE
168+
lr r3, [_ARC_V2_SEC_STAT]
169+
/* set SEC_STAT.IRM = SECURE for interrupt return */
170+
bset r3, r3, 3
171+
/* sflag r3 */
172+
/* sflag instruction is not supported in current ARC GNU */
173+
.long 0x00ff302f
174+
#endif
175+
166176
lr r3, [_ARC_V2_AUX_IRQ_ACT]
167-
brne r3,0,_swap_already_in_irq
177+
brne r3, 0, _swap_already_in_irq
168178

169-
or r3,r3,(1<<(CONFIG_NUM_IRQ_PRIO_LEVELS-1)) /* use lowest */
179+
/* use lowest interrupt priority */
180+
or r3, r3, (1<<(CONFIG_NUM_IRQ_PRIO_LEVELS-1))
170181
sr r3, [_ARC_V2_AUX_IRQ_ACT]
171182

172183
_swap_already_in_irq:

0 commit comments

Comments
 (0)