From 2833d016aa0b747c5c6fdd363dea4a9ebda941eb Mon Sep 17 00:00:00 2001 From: Wayne Ren Date: Sat, 11 Apr 2020 15:33:06 +0800 Subject: [PATCH] arch: arc: fix the bug of IRQ_ACT.U bit sync up This bug is brought in commit 3f88ddd54999. The cleanup of IRQ_ACT.U bit before thread switch is not done. The bug comes out at the case where interrupt comes in user mode, then a thread switch happens, and the target thread is to run in kernel mode. Because the U bit is not sync up correctly, the stack operation is wrong. Signed-off-by: Wayne Ren --- arch/arc/include/swap_macros.h | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/arch/arc/include/swap_macros.h b/arch/arc/include/swap_macros.h index ca83f3303f04ff..3fd38882701869 100644 --- a/arch/arc/include/swap_macros.h +++ b/arch/arc/include/swap_macros.h @@ -407,12 +407,21 @@ .macro _irq_store_old_thread_callee_regs #if defined(CONFIG_USERSPACE) /* + * when USERSPACE is enabled, according to ARCv2 ISA, SP will be switched + * if interrupt comes out in user mode, and will be recorded in bit 31 + * (U bit) of IRQ_ACT. when interrupt exits, SP will be switched back + * according to U bit. + * * need to remember the user/kernel status of interrupted thread, will be * restored when thread switched back + * */ - lr r3, [_ARC_V2_AUX_IRQ_ACT] - and r3, r3, 0x80000000 + lr r1, [_ARC_V2_AUX_IRQ_ACT] + and r3, r1, 0x80000000 push_s r3 + + bclr r1, r1, 31 + sr r1, [_ARC_V2_AUX_IRQ_ACT] #endif _store_old_thread_callee_regs .endm @@ -440,22 +449,6 @@ /* when switch to thread caused by coop, some status regs need to set */ .macro _set_misc_regs_irq_switch_from_coop -#if defined(CONFIG_USERSPACE) -/* - * when USERSPACE is enabled, according to ARCv2 ISA, SP will be switched - * if interrupt comes out in user mode, and will be recorded in bit 31 - * (U bit) of IRQ_ACT. when interrupt exits, SP will be switched back - * according to U bit. - * - * For the case that context switches in interrupt, the target sp must be - * thread's kernel stack, no need to do hardware sp switch. so, U bit should - * be cleared. - */ - lr r0, [_ARC_V2_AUX_IRQ_ACT] - bclr r0, r0, 31 - sr r0, [_ARC_V2_AUX_IRQ_ACT] -#endif - #ifdef CONFIG_ARC_SECURE_FIRMWARE /* must return to secure mode, so set IRM bit to 1 */ lr r0, [_ARC_V2_SEC_STAT]