Commit 8168f098 authored by Mark Rutland's avatar Mark Rutland Committed by Will Deacon
Browse files

arm64: entry: split bad stack entry



We'd like to keep all the entry sequencing in entry-common.c, as this
will allow us to ensure this is consistent, and free from any unsound
instrumentation.

Currently handle_bad_stack() performs the NMI entry sequence in traps.c.
Let's split the low-level entry sequence from the reporting, moving the
former to entry-common.c and keeping the latter in traps.c. To make it
clear that reporting function never returns, it is renamed to
panic_bad_stack().

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-17-mark.rutland@arm.com


Signed-off-by: default avatarWill Deacon <will@kernel.org>
parent afd05e28
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@ static inline u32 disr_to_esr(u64 disr)
	return esr;
}

asmlinkage void handle_bad_stack(struct pt_regs *regs);

asmlinkage void el1t_64_sync_handler(struct pt_regs *regs);
asmlinkage void el1t_64_irq_handler(struct pt_regs *regs);
asmlinkage void el1t_64_fiq_handler(struct pt_regs *regs);
@@ -73,4 +75,6 @@ void do_el0_svc(struct pt_regs *regs);
void do_el0_svc_compat(struct pt_regs *regs);
void do_ptrauth_fault(struct pt_regs *regs, unsigned int esr);
void do_serror(struct pt_regs *regs, unsigned int esr);

void panic_bad_stack(struct pt_regs *regs, unsigned int esr, unsigned long far);
#endif	/* __ASM_EXCEPTION_H */
+11 −0
Original line number Diff line number Diff line
@@ -699,3 +699,14 @@ UNHANDLED(el0t, 32, irq)
UNHANDLED(el0t, 32, fiq)
UNHANDLED(el0t, 32, error)
#endif /* CONFIG_COMPAT */

#ifdef CONFIG_VMAP_STACK
asmlinkage void noinstr handle_bad_stack(struct pt_regs *regs)
{
	unsigned int esr = read_sysreg(esr_el1);
	unsigned long far = read_sysreg(far_el1);

	arm64_enter_nmi(regs);
	panic_bad_stack(regs, esr, far);
}
#endif /* CONFIG_VMAP_STACK */
+1 −5
Original line number Diff line number Diff line
@@ -763,15 +763,11 @@ void bad_el0_sync(struct pt_regs *regs, int reason, unsigned int esr)
DEFINE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], overflow_stack)
	__aligned(16);

asmlinkage void noinstr handle_bad_stack(struct pt_regs *regs)
void panic_bad_stack(struct pt_regs *regs, unsigned int esr, unsigned long far)
{
	unsigned long tsk_stk = (unsigned long)current->stack;
	unsigned long irq_stk = (unsigned long)this_cpu_read(irq_stack_ptr);
	unsigned long ovf_stk = (unsigned long)this_cpu_ptr(overflow_stack);
	unsigned int esr = read_sysreg(esr_el1);
	unsigned long far = read_sysreg(far_el1);

	arm64_enter_nmi(regs);

	console_verbose();
	pr_emerg("Insufficient stack space to handle exception!");