[PATCH 16/21] arm64: entry: Implement EL1t exception handlers for overflow stack
From: Will Deacon <will@kernel.org>
Date: 2026-09-07 16:44:13
Also in:
lkml
Subsystem:
arm64 port (aarch64 architecture), the rest · Maintainers:
Catalin Marinas, Will Deacon, Linus Torvalds
In preparation for using EL1t to handle exceptions taken whilst running on the overflow stack, implement some simple wrappers around the EL1h handlers which perform a best-effort stack overflow check before proceeding. Cc: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Will Deacon <will@kernel.org> --- arch/arm64/kernel/entry-common.c | 43 +++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index 72c03ccea59f..9738142780df 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c@@ -327,10 +327,45 @@ static void debug_exception_exit(struct pt_regs *regs) } NOKPROBE_SYMBOL(debug_exception_exit); -UNHANDLED(el1t, 64, sync) -UNHANDLED(el1t, 64, irq) -UNHANDLED(el1t, 64, fiq) -UNHANDLED(el1t, 64, error) +static void noinstr el1t_64_check_overflow_stack(struct pt_regs *regs) +{ + unsigned long sp = kernel_stack_pointer(regs) - sizeof(*regs); + unsigned long ovf_stack = (unsigned long)this_cpu_ptr(overflow_stack); + + /* + * We're in big trouble if we've overflowed the overflow stack + * so perform a best-effort check before we proceed. If our SP + * is outside of the overflow stack for this CPU then presumably + * we're already corrupting memory, so park ourselves here in an + * attempt to contain the damage. + */ + if (sp < ovf_stack || sp > ovf_stack + OVERFLOW_STACK_SIZE) + cpu_park_loop(); +} + +asmlinkage void noinstr el1t_64_sync_handler(struct pt_regs *regs) +{ + el1t_64_check_overflow_stack(regs); + el1h_64_sync_handler(regs); +} + +asmlinkage void noinstr el1t_64_irq_handler(struct pt_regs *regs) +{ + el1t_64_check_overflow_stack(regs); + el1h_64_irq_handler(regs); +} + +asmlinkage void noinstr el1t_64_fiq_handler(struct pt_regs *regs) +{ + el1t_64_check_overflow_stack(regs); + el1h_64_fiq_handler(regs); +} + +asmlinkage void noinstr el1t_64_error_handler(struct pt_regs *regs) +{ + el1t_64_check_overflow_stack(regs); + el1h_64_error_handler(regs); +} static void noinstr el1_abort(struct pt_regs *regs, unsigned long esr) {
--
2.55.0.979.g7e5102b832-goog