arm64: let the core code deal with preempt_count
Commit f27dde8dee
(sched: Add NEED_RESCHED to the preempt_count)
introduced the use of bit 31 in preempt_count for obscure scheduling
purposes.
This causes interrupts taken from EL0 to hit the (open coded) BUG when
this flag is flipped while handling the interrupt (we compare the
values before and after, and kill the kernel if they are different).
The fix is to stop messing with the preempt count entirely, as this
is already being dealt with in the generic code (irq_enter/irq_exit).
Tested on a dual A53 FPGA running cyclictest.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
Родитель
6ce4eac1f6
Коммит
6468178767
|
@ -309,15 +309,12 @@ el1_irq:
|
||||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
bl trace_hardirqs_off
|
bl trace_hardirqs_off
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
irq_handler
|
||||||
|
|
||||||
#ifdef CONFIG_PREEMPT
|
#ifdef CONFIG_PREEMPT
|
||||||
get_thread_info tsk
|
get_thread_info tsk
|
||||||
ldr w24, [tsk, #TI_PREEMPT] // get preempt count
|
ldr w24, [tsk, #TI_PREEMPT] // restore preempt count
|
||||||
add w0, w24, #1 // increment it
|
|
||||||
str w0, [tsk, #TI_PREEMPT]
|
|
||||||
#endif
|
|
||||||
irq_handler
|
|
||||||
#ifdef CONFIG_PREEMPT
|
|
||||||
str w24, [tsk, #TI_PREEMPT] // restore preempt count
|
|
||||||
cbnz w24, 1f // preempt count != 0
|
cbnz w24, 1f // preempt count != 0
|
||||||
ldr x0, [tsk, #TI_FLAGS] // get flags
|
ldr x0, [tsk, #TI_FLAGS] // get flags
|
||||||
tbz x0, #TIF_NEED_RESCHED, 1f // needs rescheduling?
|
tbz x0, #TIF_NEED_RESCHED, 1f // needs rescheduling?
|
||||||
|
@ -507,22 +504,10 @@ el0_irq_naked:
|
||||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
bl trace_hardirqs_off
|
bl trace_hardirqs_off
|
||||||
#endif
|
#endif
|
||||||
get_thread_info tsk
|
|
||||||
#ifdef CONFIG_PREEMPT
|
|
||||||
ldr w24, [tsk, #TI_PREEMPT] // get preempt count
|
|
||||||
add w23, w24, #1 // increment it
|
|
||||||
str w23, [tsk, #TI_PREEMPT]
|
|
||||||
#endif
|
|
||||||
irq_handler
|
irq_handler
|
||||||
#ifdef CONFIG_PREEMPT
|
get_thread_info tsk
|
||||||
ldr w0, [tsk, #TI_PREEMPT]
|
|
||||||
str w24, [tsk, #TI_PREEMPT]
|
|
||||||
cmp w0, w23
|
|
||||||
b.eq 1f
|
|
||||||
mov x1, #0
|
|
||||||
str x1, [x1] // BUG
|
|
||||||
1:
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
bl trace_hardirqs_on
|
bl trace_hardirqs_on
|
||||||
#endif
|
#endif
|
||||||
|
|
Загрузка…
Ссылка в новой задаче