Commit 101a5b66 authored by Mark Rutland's avatar Mark Rutland Committed by Will Deacon
Browse files

arm64: entry: move NMI preempt logic to C



Currently portions of our preempt logic are written in C while other
parts are written in assembly. Let's clean this up a little bit by
moving the NMI preempt checks to C. For now, the preempt count (and
need_resched) checking is left in assembly, and will be converted
with the body of the IRQ handler in subsequent patches.

Other than the increased lockdep coverage there should be no functional
change as a result of this patch.

Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
Acked-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Acked-by: default avatarMarc Zyngier <maz@kernel.org>
Reviewed-by: default avatarJoey Gouly <joey.gouly@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20210607094624.34689-6-mark.rutland@arm.com


Signed-off-by: default avatarWill Deacon <will@kernel.org>
parent 33a3581a
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -121,6 +121,15 @@ asmlinkage void __sched arm64_preempt_schedule_irq(void)
{
	lockdep_assert_irqs_disabled();

	/*
	 * DAIF.DA are cleared at the start of IRQ/FIQ handling, and when GIC
	 * priority masking is used the GIC irqchip driver will clear DAIF.IF
	 * using gic_arch_enable_irqs() for normal IRQs. If anything is set in
	 * DAIF we must have handled an NMI, so skip preemption.
	 */
	if (system_uses_irq_prio_masking() && read_sysreg(daif))
		return;

	/*
	 * Preempting a task from an IRQ means we leave copies of PSTATE
	 * on the stack. cpufeature's enable calls may modify PSTATE, but
+1 −11
Original line number Diff line number Diff line
@@ -562,17 +562,7 @@ tsk .req x28 // current thread_info

#ifdef CONFIG_PREEMPTION
	ldr	x24, [tsk, #TSK_TI_PREEMPT]	// get preempt count
alternative_if ARM64_HAS_IRQ_PRIO_MASKING
	/*
	 * DA were cleared at start of handling, and IF are cleared by
	 * the GIC irqchip driver using gic_arch_enable_irqs() for
	 * normal IRQs. If anything is set, it means we come back from
	 * an NMI instead of a normal IRQ, so skip preemption
	 */
	mrs	x0, daif
	orr	x24, x24, x0
alternative_else_nop_endif
	cbnz	x24, 1f				// preempt count != 0 || NMI return path
	cbnz	x24, 1f				// preempt count != 0
	bl	arm64_preempt_schedule_irq	// irq en/disable is done inside
1:
#endif