From 1f0fc6d712108bdd4588e6c1d1b638b81c5b589b Mon Sep 17 00:00:00 2001 From: Wayne Ren Date: Tue, 9 Apr 2019 17:09:54 +0800 Subject: [PATCH] arch: arc: fix the bug of nest interrupt handling in int exit * it's not reliable to use exc_nest_count to decide nest interrupt. A better option is to use IRQ_ACT * ext_nest_count is just used to switch interrupt stack Signed-off-by: Wayne Ren --- arch/arc/core/fast_irq.S | 9 +++++++-- arch/arc/core/regular_irq.S | 19 +++++++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/arch/arc/core/fast_irq.S b/arch/arc/core/fast_irq.S index 7a8cc93a027..31444ab744d 100644 --- a/arch/arc/core/fast_irq.S +++ b/arch/arc/core/fast_irq.S @@ -140,9 +140,14 @@ SECTION_FUNC(TEXT, _firq_exit) mov r1, exc_nest_count ld r0, [r1] sub r0, r0, 1 - cmp r0, 0 - bne.d _firq_no_reschedule st r0, [r1] +/* see comments in _rirq_exit */ + lr r0, [_ARC_V2_AUX_IRQ_ACT] + and r0, r0, 0xffff + ffs r1, r0 + fls r2, r0 + cmp r1, r2 + jne _firq_no_reschedule #ifdef CONFIG_STACK_SENTINEL bl z_check_stack_sentinel diff --git a/arch/arc/core/regular_irq.S b/arch/arc/core/regular_irq.S index e626ec63b60..5908b692f7d 100644 --- a/arch/arc/core/regular_irq.S +++ b/arch/arc/core/regular_irq.S @@ -99,9 +99,24 @@ SECTION_FUNC(TEXT, _rirq_exit) mov r1, exc_nest_count ld r0, [r1] sub r0, r0, 1 - cmp r0, 0 - bne.d _rirq_return_from_rirq st r0, [r1] + /* + * using exc_nest_count to decide whether is nest int is not reliable. + * a better option is to use IRQ_ACT + * A case is: a high priority int preempts a low priority int before + * rirq_enter/firq_enter, then in _rirq_exit/_firq_exit, it will see + * exc_nest_cout is 0, this will lead to possible thread switch, but + * a low priority int is still pending. + * + * If multi bits in IRQ_ACT are set, i.e. last bit != fist bit, it's + * in nest interrupt + */ + lr r0, [_ARC_V2_AUX_IRQ_ACT] + and r0, r0, 0xffff + ffs r1, r0 + fls r2, r0 + cmp r1, r2 + jne _rirq_return_from_rirq #ifdef CONFIG_STACK_SENTINEL bl z_check_stack_sentinel