diff options
author | Guo Ren <guoren@linux.alibaba.com> | 2020-05-24 10:03:07 +0200 |
---|---|---|
committer | Guo Ren <guoren@linux.alibaba.com> | 2020-05-28 02:18:36 +0200 |
commit | 900897591b2bf01154db8f59f6ecf8d60e60f15e (patch) | |
tree | 8ac230ab9c4c95374dded9e9d76b55d20ac51bec /arch/csky/kernel/entry.S | |
parent | Linux 5.7-rc7 (diff) | |
download | linux-900897591b2bf01154db8f59f6ecf8d60e60f15e.tar.xz linux-900897591b2bf01154db8f59f6ecf8d60e60f15e.zip |
csky: Fixup CONFIG_PREEMPT panic
log:
[ 0.13373200] Calibrating delay loop...
[ 0.14077600] ------------[ cut here ]------------
[ 0.14116700] WARNING: CPU: 0 PID: 0 at kernel/sched/core.c:3790 preempt_count_add+0xc8/0x11c
[ 0.14348000] DEBUG_LOCKS_WARN_ON((preempt_count() < 0))Modules linked in:
[ 0.14395100] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.6.0 #7
[ 0.14410800]
[ 0.14427400] Call Trace:
[ 0.14450700] [<807cd226>] dump_stack+0x8a/0xe4
[ 0.14473500] [<80072792>] __warn+0x10e/0x15c
[ 0.14495900] [<80072852>] warn_slowpath_fmt+0x72/0xc0
[ 0.14518600] [<800a5240>] preempt_count_add+0xc8/0x11c
[ 0.14544900] [<807ef918>] _raw_spin_lock+0x28/0x68
[ 0.14572600] [<800e0eb8>] vprintk_emit+0x84/0x2d8
[ 0.14599000] [<800e113a>] vprintk_default+0x2e/0x44
[ 0.14625100] [<800e2042>] vprintk_func+0x12a/0x1d0
[ 0.14651300] [<800e1804>] printk+0x30/0x48
[ 0.14677600] [<80008052>] lockdep_init+0x12/0xb0
[ 0.14703800] [<80002080>] start_kernel+0x558/0x7f8
[ 0.14730000] [<800052bc>] csky_start+0x58/0x94
[ 0.14756600] irq event stamp: 34
[ 0.14775100] hardirqs last enabled at (33): [<80067370>] ret_from_exception+0x2c/0x72
[ 0.14793700] hardirqs last disabled at (34): [<800e0eae>] vprintk_emit+0x7a/0x2d8
[ 0.14812300] softirqs last enabled at (32): [<800655b0>] __do_softirq+0x578/0x6d8
[ 0.14830800] softirqs last disabled at (25): [<8007b3b8>] irq_exit+0xec/0x128
The preempt_count of reg could be destroyed after csky_do_IRQ without reload
from memory.
After reference to other architectures (arm64, riscv), we move preempt entry
into ret_from_exception and disable irq at the beginning of
ret_from_exception instead of RESTORE_ALL.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Reported-by: Lu Baoquan <lu.baoquan@intellif.com>
Diffstat (limited to 'arch/csky/kernel/entry.S')
-rw-r--r-- | arch/csky/kernel/entry.S | 36 |
1 files changed, 11 insertions, 25 deletions
diff --git a/arch/csky/kernel/entry.S b/arch/csky/kernel/entry.S index 3760397fdd3d..bfbef30f8a53 100644 --- a/arch/csky/kernel/entry.S +++ b/arch/csky/kernel/entry.S @@ -208,9 +208,9 @@ ENTRY(ret_from_fork) jbsr syscall_trace_exit ret_from_exception: + psrclr ie ld syscallid, (sp, LSAVE_PSR) btsti syscallid, 31 - bt 1f /* * Load address of current->thread_info, Then get address of task_struct @@ -220,11 +220,20 @@ ret_from_exception: bmaski r10, THREAD_SHIFT andn r9, r10 + bt 1f ldw r12, (r9, TINFO_FLAGS) andi r12, (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | _TIF_UPROBE) cmpnei r12, 0 bt exit_work 1: +#ifdef CONFIG_PREEMPTION + ldw r12, (r9, TINFO_PREEMPT) + cmpnei r12, 0 + bt 2f + jbsr preempt_schedule_irq /* irq en/disable is done inside */ +2: +#endif + #ifdef CONFIG_TRACE_IRQFLAGS ld r10, (sp, LSAVE_PSR) btsti r10, 6 @@ -241,6 +250,7 @@ exit_work: btsti r12, TIF_NEED_RESCHED bt work_resched + psrset ie mov a0, sp mov a1, r12 jmpi do_notify_resume @@ -291,34 +301,10 @@ ENTRY(csky_irq) jbsr trace_hardirqs_off #endif -#ifdef CONFIG_PREEMPTION - mov r9, sp /* Get current stack pointer */ - bmaski r10, THREAD_SHIFT - andn r9, r10 /* Get thread_info */ - - /* - * Get task_struct->stack.preempt_count for current, - * and increase 1. - */ - ldw r12, (r9, TINFO_PREEMPT) - addi r12, 1 - stw r12, (r9, TINFO_PREEMPT) -#endif mov a0, sp jbsr csky_do_IRQ -#ifdef CONFIG_PREEMPTION - subi r12, 1 - stw r12, (r9, TINFO_PREEMPT) - cmpnei r12, 0 - bt 2f - ldw r12, (r9, TINFO_FLAGS) - btsti r12, TIF_NEED_RESCHED - bf 2f - jbsr preempt_schedule_irq /* irq en/disable is done inside */ -#endif -2: jmpi ret_from_exception /* |