Skip to content

Commit 44c917e

Browse files
Wayne Renioannisg
authored andcommitted
arch: arc: fix the bug that interrupt stack is not switched
For the old codes, if nest interrupts come out after _isr_wrapper and before _check_nest_int_by_irq_act, then multi-bits in irq_act will be set, this will result irq stack will not be switched in correctly As a fix, it's still need to use nest interrupt counter to do interrupt stack switch as before The difference is in the past exc_nest_count is used, but here _kernel.nested/_kernel.cpus[cpu_id].nested is used. Signed-off-by: Wayne Ren <[email protected]>
1 parent 146c7e8 commit 44c917e

File tree

4 files changed

+51
-5
lines changed

4 files changed

+51
-5
lines changed

arch/arc/core/fast_irq.S

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ SECTION_FUNC(TEXT, _firq_enter)
7676
lr r25, [_ARC_V2_LP_END]
7777
#endif
7878

79-
_check_nest_int_by_irq_act r0, r1
79+
/* check whether irq stack is used */
80+
_check_and_inc_int_nest_counter r0, r1
8081

8182
bne.d firq_nest
8283
mov r0, sp
@@ -138,6 +139,7 @@ SECTION_FUNC(TEXT, _firq_exit)
138139
sr r24, [_ARC_V2_LP_START]
139140
sr r25, [_ARC_V2_LP_END]
140141
#endif
142+
_dec_int_nest_counter r0, r1
141143

142144
_check_nest_int_by_irq_act r0, r1
143145

arch/arc/core/fault_s.S

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,9 +246,9 @@ _do_non_syscall_trap:
246246
st_s r0, [sp, ___isf_t_pc_OFFSET] /* eret into pc */
247247

248248

249-
lr r0, [_ARC_V2_AUX_IRQ_ACT]
250-
and r0, r0, 0xffff
251-
cmp r0, 0
249+
/* check whether irq stack is used */
250+
_check_and_inc_int_nest_counter r0, r1
251+
252252
bne.d exc_nest_handle
253253
mov r0, sp
254254

@@ -260,6 +260,8 @@ exc_nest_handle:
260260

261261
pop sp
262262

263+
_dec_int_nest_counter r0, r1
264+
263265
lr r0, [_ARC_V2_AUX_IRQ_ACT]
264266
and r0, r0, 0xffff
265267
cmp r0, 0

arch/arc/core/regular_irq.S

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ SECTION_FUNC(TEXT, _rirq_enter)
6767
#endif
6868
clri
6969

70-
_check_nest_int_by_irq_act r0, r1
70+
/* check whether irq stack is used */
71+
_check_and_inc_int_nest_counter r0, r1
7172

7273
bne.d rirq_nest
7374
mov r0, sp
@@ -92,6 +93,8 @@ SECTION_FUNC(TEXT, _rirq_exit)
9293

9394
pop sp
9495

96+
_dec_int_nest_counter r0, r1
97+
9598
_check_nest_int_by_irq_act r0, r1
9699

97100
jne _rirq_no_reschedule

arch/arc/include/swap_macros.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,45 @@
294294
#endif /* CONFIG_ARC_SECURE_FIRMWARE */
295295
.endm
296296

297+
/* check and increase the interrupt nest counter
298+
* after increase, check whether nest counter == 1
299+
* the result will be EQ bit of status32
300+
*/
301+
.macro _check_and_inc_int_nest_counter reg1 reg2
302+
#ifdef CONFIG_SMP
303+
_get_cpu_id \reg1
304+
ld.as \reg1, [@_curr_cpu, \reg1]
305+
ld \reg2, [\reg1, ___cpu_t_nested_OFFSET]
306+
#else
307+
mov \reg1, _kernel
308+
ld \reg2, [\reg1, ___kernel_t_nested_OFFSET]
309+
#endif
310+
add \reg2, \reg2, 1
311+
#ifdef CONFIG_SMP
312+
st \reg2, [\reg1, ___cpu_t_nested_OFFSET]
313+
#else
314+
st \reg2, [\reg1, ___kernel_t_nested_OFFSET]
315+
#endif
316+
cmp \reg2, 1
317+
.endm
318+
319+
/* decrease interrupt nest counter */
320+
.macro _dec_int_nest_counter reg1 reg2
321+
#ifdef CONFIG_SMP
322+
_get_cpu_id \reg1
323+
ld.as \reg1, [@_curr_cpu, \reg1]
324+
ld \reg2, [\reg1, ___cpu_t_nested_OFFSET]
325+
#else
326+
mov \reg1, _kernel
327+
ld \reg2, [\reg1, ___kernel_t_nested_OFFSET]
328+
#endif
329+
sub \reg2, \reg2, 1
330+
#ifdef CONFIG_SMP
331+
st \reg2, [\reg1, ___cpu_t_nested_OFFSET]
332+
#else
333+
st \reg2, [\reg1, ___kernel_t_nested_OFFSET]
334+
#endif
335+
.endm
297336

298337
/* If multi bits in IRQ_ACT are set, i.e. last bit != fist bit, it's
299338
* in nest interrupt. The result will be EQ bit of status32

0 commit comments

Comments
 (0)