From: Mostafa Saleh <smostafa@google.com>
To: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, linux-mm@kvack.org,
linux-hardening@vger.kernel.org, linux-rt-devel@lists.linux.dev
Cc: corbet@lwn.net, skhan@linuxfoundation.org, rdunlap@infradead.org,
catalin.marinas@arm.com, will@kernel.org, mark.rutland@arm.com,
akpm@linux-foundation.org, urezki@gmail.com, mingo@redhat.com,
peterz@infradead.org, juri.lelli@redhat.com,
vincent.guittot@linaro.org, dietmar.eggemann@arm.com,
rostedt@goodmis.org, bsegall@google.com, mgorman@suse.de,
vschneid@redhat.com, kprateek.nayak@amd.com, kees@kernel.org,
david@kernel.org, ljs@kernel.org, liam@infradead.org,
vbabka@kernel.org, rppt@kernel.org, surenb@google.com,
mhocko@suse.com, gustavoars@kernel.org, bigeasy@linutronix.de,
clrkwllms@kernel.org, Mostafa Saleh <smostafa@google.com>
Subject: [RFC PATCH 14/15] arm64: mm: Relax kernel stack alignment
Date: Mon, 28 Sep 2026 17:41:21 +0000 [thread overview]
Message-ID: <20260928174122.3380703-15-smostafa@google.com> (raw)
In-Reply-To: <20260928174122.3380703-1-smostafa@google.com>
On the kernel entry it was not possible to use the stack until it
was checked for overflow which was done by a clever trick relying
on aligning the kernel stack to double it's size, so if the
bit at THREAD_SHIFT was set it means that the stack pointer has
overflowed.
Now, we can easily switch the sp to sp_el1 which is the overflow
stack, push some registers and execute more complex flow.
Rework the kernel entry code to eliminate the tbnz check and the
alignment requirement.
Signed-off-by: Mostafa Saleh <smostafa@google.com>
---
arch/arm64/include/asm/memory.h | 7 +--
arch/arm64/kernel/entry.S | 87 ++++++++++++++++++++++++++++-----
2 files changed, 77 insertions(+), 17 deletions(-)
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 93ce6ef65573..4545d9b39bd5 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -130,12 +130,7 @@
#define THREAD_SIZE (UL(1) << THREAD_SHIFT)
-/*
- * By aligning VMAP'd stacks to 2 * THREAD_SIZE, we can detect overflow by
- * checking sp & (1 << THREAD_SHIFT), which we can do cheaply in the entry
- * assembly.
- */
-#define THREAD_ALIGN (2 * THREAD_SIZE)
+#define THREAD_ALIGN THREAD_SIZE
#define IRQ_STACK_SIZE THREAD_SIZE
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index a31ef890a2ee..ea733b673970 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -62,15 +62,33 @@
sub sp, sp, #PT_REGS_SIZE
/*
- * Test whether the SP has overflowed, without corrupting a GPR.
- * Task and IRQ stacks are aligned so that SP & (1 << THREAD_SHIFT)
- * should always be zero.
+ * Test whether the SP has overflowed, using the overflow stack.
+ * As we do not know if the CPU was in process or irq context, first
+ * check against the task stack if that failed it means it might have
+ * been an interrupt, so check against an interrupt stack, if both
+ * failed it means that at least one of the stacks overflowed.
*/
- add sp, sp, x0 // sp' = sp + x0
- sub x0, sp, x0 // x0' = sp' - x0 = (sp + x0) - x0 = sp
- tbnz x0, #THREAD_SHIFT, __bad_stack
- sub x0, sp, x0 // x0'' = sp' - x0' = (sp + x0) - sp = x0
- sub sp, sp, x0 // sp'' = sp' - x0 = (sp + x0) - x0 = sp
+ msr spsel, #1
+ stp x0, x1, [sp, #-16]!
+
+ mrs x0, tpidrro_el0
+ ldr x0, [x0, #TSK_STACK]
+ msr spsel, #0
+ mov x1, sp
+ msr spsel, #1
+ sub x1, x1, x0
+ cmp x1, #THREAD_SIZE
+ b.lo .Lstack_ok\@
+
+ /* Check whether we are on the IRQ, SDEI or EFI stacks. */
+ stp x2, x30, [sp, #-16]!
+ bl __check_ext_stacks
+ ldp x2, x30, [sp], #16
+
+.Lstack_ok\@:
+ ldp x0, x1, [sp], #16
+ msr spsel, #0
+
b el1t_\regsize\()_\label
.endm
@@ -528,13 +546,60 @@ SYM_CODE_START(vectors)
kernel_ventry 0, t, 32, error // Error 32-bit EL0
SYM_CODE_END(vectors)
+
+ .macro check_stack_overflow type, ptr, size
+ .ifc \type, percpu
+ ldr_this_cpu x1, \ptr, x0
+ .else
+ adr_l x1, \ptr
+ ldr x1, [x1]
+ .endif
+ cbz x1, 1f
+ .ifc \type, top
+ sub x1, x1, #\size
+ .endif
+ msr spsel, #0
+ mov x0, sp
+ msr spsel, #1
+ sub x0, x0, x1
+ cmp x0, #\size
+ b.lo 2f
+1:
+ .endm
+
+SYM_CODE_START_LOCAL(__check_ext_stacks)
+ /* IRQ stack check */
+ check_stack_overflow percpu, irq_stack_ptr, IRQ_STACK_SIZE
+#ifdef CONFIG_ARM_SDE_INTERFACE
+ /* SDEI normal stack check */
+ check_stack_overflow percpu, sdei_stack_normal_ptr, IRQ_STACK_SIZE
+ /* SDEI critical stack check */
+ check_stack_overflow percpu, sdei_stack_critical_ptr, IRQ_STACK_SIZE
+#endif
+
+#ifdef CONFIG_EFI
+ /* EFI runtime stack check */
+ check_stack_overflow top, efi_rt_stack_top, THREAD_SIZE
+#endif
+
+ /* All checks failed => it's a real overflow */
+ ldp x2, x30, [sp], #16
+ b __bad_stack
+
+2:
+ /* A check succeeded => return to kernel_ventry */
+ ret
+SYM_CODE_END(__check_ext_stacks)
+
SYM_CODE_START_LOCAL(__bad_stack)
/*
* We detected an overflow in kernel_ventry.
- * Restore SP and X0.
+ * Restore X0 and X1, and pop the overflow stack.
*/
- sub x0, sp, x0
- sub sp, sp, x0
+ ldp x0, x1, [sp], #16
+
+ /* Restore SP_EL0 */
+ msr spsel, #0
add sp, sp, #PT_REGS_SIZE
/* Switch to the overflow stack */
--
2.56.0.rc1.315.gc6ed9934b7-goog
next prev parent reply other threads:[~2026-09-28 17:43 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-28 17:41 [RFC PATCH 00/15] arm64: Set kernel stack size from cmdline Mostafa Saleh
2026-09-28 17:41 ` [RFC PATCH 01/15] fork: Remove assumption that vm_area->nr_pages equals to THREAD_SIZE Mostafa Saleh
2026-09-28 17:41 ` [RFC PATCH 02/15] fork: Don't assume fully populated stack during reuse Mostafa Saleh
2026-09-28 17:41 ` [RFC PATCH 03/15] fork: Move vm_stack to the beginning of the stack Mostafa Saleh
2026-09-28 17:41 ` [RFC PATCH 04/15] fork: Separate vmap stack allocation and free calls Mostafa Saleh
2026-09-28 17:41 ` [RFC PATCH 05/15] sched/task_stack: Add helpers for stack high/low Mostafa Saleh
2026-09-28 17:41 ` [RFC PATCH 06/15] exit: Don't assume the kernel stack size Mostafa Saleh
2026-09-28 17:41 ` [RFC PATCH 07/15] usercopy: " Mostafa Saleh
2026-09-28 17:41 ` [RFC PATCH 08/15] mm: kmemleak: " Mostafa Saleh
2026-09-28 17:41 ` [RFC PATCH 09/15] arm64: " Mostafa Saleh
2026-09-28 17:41 ` [RFC PATCH 10/15] mm/vmalloc: Add a get_vm_area_node() Mostafa Saleh
2026-09-28 17:41 ` [RFC PATCH 11/15] fork: Move vmap stack freeing to work queue Mostafa Saleh
2026-09-28 17:41 ` [RFC PATCH 12/15] sched/task_stack: Introduce ARCH_HAS_VARIABLE_STACK_SIZE Mostafa Saleh
2026-09-28 20:37 ` Randy Dunlap
2026-09-29 10:27 ` Mostafa Saleh
2026-09-28 17:41 ` [RFC PATCH 13/15] fork: Implement partial VMAP stack allocation Mostafa Saleh
2026-09-28 17:41 ` Mostafa Saleh [this message]
2026-09-28 17:41 ` [RFC PATCH 15/15] arm64: mm: Set stack size from the kernel command line Mostafa Saleh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260928174122.3380703-15-smostafa@google.com \
--to=smostafa@google.com \
--cc=akpm@linux-foundation.org \
--cc=bigeasy@linutronix.de \
--cc=bsegall@google.com \
--cc=catalin.marinas@arm.com \
--cc=clrkwllms@kernel.org \
--cc=corbet@lwn.net \
--cc=david@kernel.org \
--cc=dietmar.eggemann@arm.com \
--cc=gustavoars@kernel.org \
--cc=juri.lelli@redhat.com \
--cc=kees@kernel.org \
--cc=kprateek.nayak@amd.com \
--cc=liam@infradead.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-rt-devel@lists.linux.dev \
--cc=ljs@kernel.org \
--cc=mark.rutland@arm.com \
--cc=mgorman@suse.de \
--cc=mhocko@suse.com \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=rdunlap@infradead.org \
--cc=rostedt@goodmis.org \
--cc=rppt@kernel.org \
--cc=skhan@linuxfoundation.org \
--cc=surenb@google.com \
--cc=urezki@gmail.com \
--cc=vbabka@kernel.org \
--cc=vincent.guittot@linaro.org \
--cc=vschneid@redhat.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.