arm64: let the core code deal with preempt_count
authorMarc Zyngier <Marc.Zyngier@arm.com>
Tue, 12 Nov 2013 17:11:53 +0000 (17:11 +0000)
committerCatalin Marinas <catalin.marinas@arm.com>
Mon, 25 Nov 2013 16:44:04 +0000 (16:44 +0000)
Commit f27dde8deef3 (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>
arch/arm64/kernel/entry.S

index e116614..4d2c6f3 100644 (file)
@@ -309,15 +309,12 @@ el1_irq:
 #ifdef CONFIG_TRACE_IRQFLAGS
        bl      trace_hardirqs_off
 #endif
-#ifdef CONFIG_PREEMPT
-       get_thread_info tsk
-       ldr     w24, [tsk, #TI_PREEMPT]         // get 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
+       get_thread_info tsk
+       ldr     w24, [tsk, #TI_PREEMPT]         // restore preempt count
        cbnz    w24, 1f                         // preempt count != 0
        ldr     x0, [tsk, #TI_FLAGS]            // get flags
        tbz     x0, #TIF_NEED_RESCHED, 1f       // needs rescheduling?
@@ -507,22 +504,10 @@ el0_irq_naked:
 #ifdef CONFIG_TRACE_IRQFLAGS
        bl      trace_hardirqs_off
 #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
-#ifdef CONFIG_PREEMPT
-       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
+       get_thread_info tsk
+
 #ifdef CONFIG_TRACE_IRQFLAGS
        bl      trace_hardirqs_on
 #endif