[PATCH 00/21] arm64: Move overflow sp into SP_EL1 and kernel sp into SP_EL0

Will Deacon posted 21 patches 2 weeks, 4 days ago
There is a newer version of this series
arch/arm64/Kconfig                            |   2 +-
arch/arm64/Makefile                           |   2 +-
arch/arm64/include/asm/assembler.h            |   2 +-
arch/arm64/include/asm/current.h              |   6 +-
arch/arm64/include/asm/ftrace.h               |   4 +-
arch/arm64/include/asm/insn.h                 |   1 +
arch/arm64/include/asm/kvm_asm.h              |  26 +++++
arch/arm64/include/asm/memory.h               |  10 +-
arch/arm64/include/asm/percpu.h               |  10 +-
arch/arm64/include/asm/perf_event.h           |   2 +-
arch/arm64/include/asm/sdei.h                 |   2 +
arch/arm64/include/asm/stacktrace.h           |   9 +-
arch/arm64/include/asm/stacktrace/nvhe.h      |   3 +-
arch/arm64/include/uapi/asm/ptrace.h          |   1 +
arch/arm64/kernel/asm-offsets.c               |   2 +
arch/arm64/kernel/entry-common.c              |  51 +++++++--
arch/arm64/kernel/entry.S                     | 108 +++++++++---------
arch/arm64/kernel/head.S                      |   8 +-
arch/arm64/kernel/hyp-stub.S                  |   7 +-
arch/arm64/kernel/process.c                   |  21 +---
arch/arm64/kernel/sdei.c                      |   6 +-
arch/arm64/kernel/smp.c                       |  19 ++-
arch/arm64/kernel/stacktrace.c                |   2 +-
arch/arm64/kernel/sys_compat.c                |   7 --
arch/arm64/kernel/traps.c                     |  14 +--
arch/arm64/kvm/hyp/entry.S                    |  15 ++-
arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h    |   2 -
arch/arm64/kvm/hyp/nvhe/host.S                |   2 +-
arch/arm64/kvm/hyp/nvhe/stacktrace.c          |   4 +-
arch/arm64/kvm/stacktrace.c                   |   4 +-
arch/arm64/mm/proc.S                          |   3 +
arch/arm64/net/bpf_jit.h                      |   2 +
arch/arm64/net/bpf_jit_comp.c                 |   4 +-
scripts/gdb/linux/cpus.py                     |   2 +-
.../selftests/bpf/progs/verifier_jit_inline.c |   2 +-
35 files changed, 218 insertions(+), 147 deletions(-)
[PATCH 00/21] arm64: Move overflow sp into SP_EL1 and kernel sp into SP_EL0
Posted by Will Deacon 2 weeks, 4 days ago
Hi everyone,

This series is a bit of a complicated juggling act that, on its own,
doesn't achieve an awful lot. However, it lays the ground work for
sizing the kernel stack at runtime, e.g. via a cmdline option or even
potentially on a per-task basis and so I would like to work towards
getting it merged independently.

The series is based on v7.3-rc1 and structured as follows:

  * The first 9 patches move the 'current' task pointer from SP_EL0
    to TPIDRRO_EL0.

  * The following 8 patches point the newly-freed SP_EL0 at the overflow
    stack and switch to it explicitly when we detect a kernel stack
    overflow.

  * The final 4 patches turn everything on its head, so that the
    overflow stack and kernel stack are swapped, with the former now
    residing in SP_EL1 and the latter in SP_EL0.

At the end of all that, when we take an exception from EL1, we are
immediately transitioned to the overflow stack (now renamed "exception
stack") and can push registers right away. This also means that using
SPINTMASK to control NMI masking becomes a possibility, although
speaking to Mark, Vladimir and Ada, they all seem to prefer ALLINT.

Mostafa will soon post a follow-up series that allows the kernel stack
size to be specified on the kernel cmdline, which we are hoping to use
to configure an 8k stack size in Android. I will be talking more about
all of this at LPC in the Memory Management MC:

  https://lpc.events/event/20/contributions/2419/

Cheers,

Will

Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Cc: David Hildenbrand <david@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Vladimir Murzin <vladimir.murzin@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mostafa Saleh <smostafa@google.com>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Oliver Upton <oupton@kernel.org>
Cc: Linus Walleij <linusw@kernel.org>
Cc: Marc Zyngier <maz@kernel.org>

--->8

Mostafa Saleh (1):
  KVM: arm64: Protect TPIDRRO_EL0 across guest entry/exit

Will Deacon (20):
  arm64: entry: Defer setting of TPIDRRO_EL0 until exit to userspace
  arm64: entry: Only check for stack overflow on exceptions from EL1
  arm64: stackprotector: Temporarily disable per-task stackprotector
  arm64: bpf: Add support for generating reads of TPIDRRO_EL0
  arm64: Store 'current' in TPIDRRO_EL0 instead of SP_EL0
  selftests/bpf: arm64: Use TPIDRRO_EL0 instead of SP_EL0 for 'current'
  scripts/gdb: arm64: Use TPIDRRO_EL0 instead of SP_EL0 for 'current'
  arm64: stackprotector: Re-enable per-task stackprotector
  arm64: percpu: Specialise set_my_cpu_offset() for the primary CPU
  arm64: percpu: Annotate __kern_my_cpu_offset() as '__always_inline'
  KVM: arm64: Preserve handler/thread bit of EL1 mode in
    __finalise_el2()
  arm64: sdei: Guard most of asm/sdei.h with CONFIG_ARM_SDE_INTERFACE
  arm64: sdei: Support SDEI events from kernel handler and thread modes
  arm64: entry: Point SP_EL0 at the overflow stack
  arm64: entry: Implement EL1t exception handlers for overflow stack
  arm64: entry: Use SPSel to switch to overflow stack
  arm64: entry: Split up kernel_ventry macro into separate helper macros
  arm64: entry: The great stack switcheroo
  arm64: tracing: Advertise a mode of EL1t in synthetic kernel regs
  arm64: Rename 'overflow_stack' and OVERFLOW_STACK_SIZE

 arch/arm64/Kconfig                            |   2 +-
 arch/arm64/Makefile                           |   2 +-
 arch/arm64/include/asm/assembler.h            |   2 +-
 arch/arm64/include/asm/current.h              |   6 +-
 arch/arm64/include/asm/ftrace.h               |   4 +-
 arch/arm64/include/asm/insn.h                 |   1 +
 arch/arm64/include/asm/kvm_asm.h              |  26 +++++
 arch/arm64/include/asm/memory.h               |  10 +-
 arch/arm64/include/asm/percpu.h               |  10 +-
 arch/arm64/include/asm/perf_event.h           |   2 +-
 arch/arm64/include/asm/sdei.h                 |   2 +
 arch/arm64/include/asm/stacktrace.h           |   9 +-
 arch/arm64/include/asm/stacktrace/nvhe.h      |   3 +-
 arch/arm64/include/uapi/asm/ptrace.h          |   1 +
 arch/arm64/kernel/asm-offsets.c               |   2 +
 arch/arm64/kernel/entry-common.c              |  51 +++++++--
 arch/arm64/kernel/entry.S                     | 108 +++++++++---------
 arch/arm64/kernel/head.S                      |   8 +-
 arch/arm64/kernel/hyp-stub.S                  |   7 +-
 arch/arm64/kernel/process.c                   |  21 +---
 arch/arm64/kernel/sdei.c                      |   6 +-
 arch/arm64/kernel/smp.c                       |  19 ++-
 arch/arm64/kernel/stacktrace.c                |   2 +-
 arch/arm64/kernel/sys_compat.c                |   7 --
 arch/arm64/kernel/traps.c                     |  14 +--
 arch/arm64/kvm/hyp/entry.S                    |  15 ++-
 arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h    |   2 -
 arch/arm64/kvm/hyp/nvhe/host.S                |   2 +-
 arch/arm64/kvm/hyp/nvhe/stacktrace.c          |   4 +-
 arch/arm64/kvm/stacktrace.c                   |   4 +-
 arch/arm64/mm/proc.S                          |   3 +
 arch/arm64/net/bpf_jit.h                      |   2 +
 arch/arm64/net/bpf_jit_comp.c                 |   4 +-
 scripts/gdb/linux/cpus.py                     |   2 +-
 .../selftests/bpf/progs/verifier_jit_inline.c |   2 +-
 35 files changed, 218 insertions(+), 147 deletions(-)

-- 
2.55.0.979.g7e5102b832-goog
Re: [PATCH 00/21] arm64: Move overflow sp into SP_EL1 and kernel sp into SP_EL0
Posted by Vladimir Murzin 2 weeks, 2 days ago
Hi Will,

On 9/7/26 17:42, Will Deacon wrote:
> Hi everyone,
> 
> This series is a bit of a complicated juggling act that, on its own,
> doesn't achieve an awful lot. However, it lays the ground work for
> sizing the kernel stack at runtime, e.g. via a cmdline option or even
> potentially on a per-task basis and so I would like to work towards
> getting it merged independently.
> 
> The series is based on v7.3-rc1 and structured as follows:
> 
>   * The first 9 patches move the 'current' task pointer from SP_EL0
>     to TPIDRRO_EL0.
> 
>   * The following 8 patches point the newly-freed SP_EL0 at the overflow
>     stack and switch to it explicitly when we detect a kernel stack
>     overflow.
> 
>   * The final 4 patches turn everything on its head, so that the
>     overflow stack and kernel stack are swapped, with the former now
>     residing in SP_EL1 and the latter in SP_EL0.
> 
> At the end of all that, when we take an exception from EL1, we are
> immediately transitioned to the overflow stack (now renamed "exception
> stack") and can push registers right away. This also means that using
> SPINTMASK to control NMI masking becomes a possibility, although
> speaking to Mark, Vladimir and Ada, they all seem to prefer ALLINT.
> 
> Mostafa will soon post a follow-up series that allows the kernel stack
> size to be specified on the kernel cmdline, which we are hoping to use
> to configure an 8k stack size in Android. I will be talking more about
> all of this at LPC in the Memory Management MC:
> 
>   https://lpc.events/event/20/contributions/2419/
> 
> Cheers,
> 
> Will
> 
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Ard Biesheuvel <ardb@kernel.org>
> Cc: Ada Couprie Diaz <ada.coupriediaz@arm.com>
> Cc: David Hildenbrand <david@kernel.org>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Vladimir Murzin <vladimir.murzin@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Mostafa Saleh <smostafa@google.com>
> Cc: Lorenzo Stoakes <ljs@kernel.org>
> Cc: Oliver Upton <oupton@kernel.org>
> Cc: Linus Walleij <linusw@kernel.org>
> Cc: Marc Zyngier <maz@kernel.org>
> 
I gave it a try and I observe splat:

Unable to handle kernel execute from non-executable memory at virtual address ffff000970e81148
Mem abort info:
  ESR = 0x000000008600000f
  EC = 0x21: IABT (current EL), IL = 32 bits
  SET = 0, FnV = 0
  EA = 0, S1PTW = 0
  FSC = 0x0f: level 3 permission fault
swapper pgtable: 4k pages, 48-bit VAs, pgdp=000000008129f000
[ffff000970e81148] pgd=0000000000000000, p4d=18000009f1dff403, pud=18000009f1079403, pmd=18000009f0ef1403, pte=00e80009f0e81707
Internal error: Oops: 000000008600000f [#1]  SMP
Modules linked in:
CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 7.3.0-rc2-7fb054f87+ #3627 PREEMPT(lazy) 
Hardware name: Generated (DT)
pstate: 1634023c9 (nZCv DAIF +ALLINT +PAN -UAO +TCO +DIT -SSBS BTYPE=--)
pc : 0xffff000970e81148
lr : 0xffff000970e81148
sp : ffff000970e81150
x29: ffff800080f85fc0 x28: 0000000000000001 x27: 0000000000002000
x26: 0000000000000000 x25: 00000000000000c0 x24: 0000000040000023
x23: ffff800080c0e1d8 x22: 00000000000003c0 x21: ffff800080b58300
x20: cfa2800080b58300 x19: 00000000200003c0 x18: 0000000000000000
x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000028
x14: 0000000000000000 x13: ffff8000814f3ac0 x12: ffff8008efcac000
x11: b2000c3eb474d99d x10: 0000000000000008 x9 : 0000000000001000
x8 : ffff800080010800 x7 : 055001f2b5503510 x6 : 0000000001310000
x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffff800081502d80
x2 : 0000000000000802 x1 : ffff000800106a70 x0 : 0000000000000001
Call trace:
 0xffff000970e81148 (P)
Code: 00000000 00000000 00000000 00000000 (00000002) 
---[ end trace 0000000000000000 ]---
Kernel panic - not syncing: Oops: Fatal exception
SMP: stopping secondary CPUs
Kernel Offset: disabled
CPU features: 0x0,00000000,034bfc7d,ff728b42,7ffce667
Memory Limit: none
---[ end Kernel panic - not syncing: Oops: Fatal exception ]---

I suspect it is related to power management, since it can be triggered
with the sleep command, though I haven't debugged it. I noticed that
Sashiko has reported issues related to suspend/resume, so if you
provide fixups for the relevant commits, I can give them another
try. Otherwise, I'll wait for v2 :)

Cheers
Vladimir
Re: [PATCH 00/21] arm64: Move overflow sp into SP_EL1 and kernel sp into SP_EL0
Posted by Will Deacon 2 weeks, 2 days ago
Hi Vladimir,

On Wed, Sep 09, 2026 at 11:39:24AM +0100, Vladimir Murzin wrote:
> On 9/7/26 17:42, Will Deacon wrote:
> > This series is a bit of a complicated juggling act that, on its own,
> > doesn't achieve an awful lot. However, it lays the ground work for
> > sizing the kernel stack at runtime, e.g. via a cmdline option or even
> > potentially on a per-task basis and so I would like to work towards
> > getting it merged independently.

[...]

> I gave it a try and I observe splat:

Thanks for taking it for a spin!

> Unable to handle kernel execute from non-executable memory at virtual address ffff000970e81148
> Mem abort info:
>   ESR = 0x000000008600000f
>   EC = 0x21: IABT (current EL), IL = 32 bits
>   SET = 0, FnV = 0
>   EA = 0, S1PTW = 0
>   FSC = 0x0f: level 3 permission fault
> swapper pgtable: 4k pages, 48-bit VAs, pgdp=000000008129f000
> [ffff000970e81148] pgd=0000000000000000, p4d=18000009f1dff403, pud=18000009f1079403, pmd=18000009f0ef1403, pte=00e80009f0e81707
> Internal error: Oops: 000000008600000f [#1]  SMP
> Modules linked in:
> CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 7.3.0-rc2-7fb054f87+ #3627 PREEMPT(lazy) 
> Hardware name: Generated (DT)
> pstate: 1634023c9 (nZCv DAIF +ALLINT +PAN -UAO +TCO +DIT -SSBS BTYPE=--)
> pc : 0xffff000970e81148
> lr : 0xffff000970e81148
> sp : ffff000970e81150
> x29: ffff800080f85fc0 x28: 0000000000000001 x27: 0000000000002000
> x26: 0000000000000000 x25: 00000000000000c0 x24: 0000000040000023
> x23: ffff800080c0e1d8 x22: 00000000000003c0 x21: ffff800080b58300
> x20: cfa2800080b58300 x19: 00000000200003c0 x18: 0000000000000000
> x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000028
> x14: 0000000000000000 x13: ffff8000814f3ac0 x12: ffff8008efcac000
> x11: b2000c3eb474d99d x10: 0000000000000008 x9 : 0000000000001000
> x8 : ffff800080010800 x7 : 055001f2b5503510 x6 : 0000000001310000
> x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffff800081502d80
> x2 : 0000000000000802 x1 : ffff000800106a70 x0 : 0000000000000001
> Call trace:
>  0xffff000970e81148 (P)
> Code: 00000000 00000000 00000000 00000000 (00000002) 
> ---[ end trace 0000000000000000 ]---
> Kernel panic - not syncing: Oops: Fatal exception
> SMP: stopping secondary CPUs
> Kernel Offset: disabled
> CPU features: 0x0,00000000,034bfc7d,ff728b42,7ffce667
> Memory Limit: none
> ---[ end Kernel panic - not syncing: Oops: Fatal exception ]---
> 
> I suspect it is related to power management, since it can be triggered
> with the sleep command, though I haven't debugged it. I noticed that
> Sashiko has reported issues related to suspend/resume, so if you
> provide fixups for the relevant commits, I can give them another
> try. Otherwise, I'll wait for v2 :)

It's fiddly to envisage how we end up trying to execute from non-executable
memory, but there are two bugs in the suspend/resume code:

1. I don't save/restore the stack pointers correctly (I suppose this could
   explain almost any crash, tbh)

2. I don't restore the pauth keys properly

I've hacked up an untested diff below, please can you take it for a spin?

Cheers,

Will

--->8

diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S
index f093cdf71be1..facf3f1cc3b1 100644
--- a/arch/arm64/kernel/sleep.S
+++ b/arch/arm64/kernel/sleep.S
@@ -133,7 +133,8 @@ SYM_FUNC_START(_cpu_resume)
 	add	x0, x0, #SLEEP_STACK_DATA_SYSTEM_REGS
 	/* load sp from context */
 	ldr	x2, [x0, #CPU_CTX_SP]
-	mov	sp, x2
+	msr	sp_el0, x2
+
 	/*
 	 * cpu_do_resume expects x0 to contain context address pointer
 	 */
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 0811fa569100..bec7f858fae9 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -87,6 +87,7 @@
  * This must be kept in sync with struct cpu_suspend_ctx in <asm/suspend.h>.
  */
 SYM_FUNC_START(cpu_do_suspend)
+	msr	spsel, #1
 	mrs	x2, tpidr_el0
 	mrs	x3, tpidrro_el0
 	mrs	x4, contextidr_el1
@@ -98,8 +99,7 @@ SYM_FUNC_START(cpu_do_suspend)
 	mrs	x10, oslsr_el1
 	mrs	x11, sctlr_el1
 	get_this_cpu_offset x12
-	msr	spsel, #1
-	mrs	x13, sp_el0
+	mov	x13, sp				// SP_EL1
 	stp	x2, x3, [x0]
 	stp	x4, x5, [x0, #16]
 	stp	x6, x7, [x0, #32]
@@ -115,6 +115,7 @@ alternative_if ARM64_HAS_TCR2
 	mrs	x2, REG_TCR2_EL1
 	str	x2, [x0, #104]
 alternative_else_nop_endif
+	msr	spsel, #0
 	ret
 SYM_FUNC_END(cpu_do_suspend)
 
@@ -122,6 +123,8 @@ SYM_FUNC_END(cpu_do_suspend)
  * cpu_do_resume - restore CPU register context
  *
  * x0: Address of context pointer
+ *
+ * Entered with SPSel == 1, returns with SPSel == 0.
  */
 SYM_FUNC_START(cpu_do_resume)
 	ldp	x2, x3, [x0]
@@ -130,6 +133,10 @@ SYM_FUNC_START(cpu_do_resume)
 	ldp	x9, x10, [x0, #48]
 	ldp	x11, x12, [x0, #64]
 	ldp	x13, x14, [x0, #80]
+
+	/* Move 'current' somewhere safe */
+	mov	x15, x3
+
 	/*
 	 * Restore x18, as it may be used as a platform register, and clear
 	 * the buffer to minimize the risk of exposure when used for shadow
@@ -156,8 +163,7 @@ alternative_else_nop_endif
 
 	msr	sctlr_el1, x12
 	set_this_cpu_offset x13
-	msr	sp_el0, x14
-	msr	spsel, #0
+	mov	sp, x14				// SP_EL1
 
 	/*
 	 * Restore oslsr_el1 by writing oslar_el1
@@ -179,8 +185,9 @@ alternative_if ARM64_HAS_GIC_PRIO_MASKING
 alternative_else_nop_endif
 #endif
 
-	ptrauth_keys_install_kernel_nosync x14, x1, x2, x3
+	ptrauth_keys_install_kernel_nosync x15, x1, x2, x3
 	isb
+	msr	spsel, #0
 	ret
 SYM_FUNC_END(cpu_do_resume)
 #endif
Re: [PATCH 00/21] arm64: Move overflow sp into SP_EL1 and kernel sp into SP_EL0
Posted by Vladimir Murzin 2 weeks, 1 day ago
Hi Will,

On 9/9/26 12:29, Will Deacon wrote:
> Hi Vladimir,
> 
> On Wed, Sep 09, 2026 at 11:39:24AM +0100, Vladimir Murzin wrote:
>> On 9/7/26 17:42, Will Deacon wrote:
>>> This series is a bit of a complicated juggling act that, on its own,
>>> doesn't achieve an awful lot. However, it lays the ground work for
>>> sizing the kernel stack at runtime, e.g. via a cmdline option or even
>>> potentially on a per-task basis and so I would like to work towards
>>> getting it merged independently.
> [...]
> 
>> I gave it a try and I observe splat:
> Thanks for taking it for a spin!
> 
>> Unable to handle kernel execute from non-executable memory at virtual address ffff000970e81148
>> Mem abort info:
>>   ESR = 0x000000008600000f
>>   EC = 0x21: IABT (current EL), IL = 32 bits
>>   SET = 0, FnV = 0
>>   EA = 0, S1PTW = 0
>>   FSC = 0x0f: level 3 permission fault
>> swapper pgtable: 4k pages, 48-bit VAs, pgdp=000000008129f000
>> [ffff000970e81148] pgd=0000000000000000, p4d=18000009f1dff403, pud=18000009f1079403, pmd=18000009f0ef1403, pte=00e80009f0e81707
>> Internal error: Oops: 000000008600000f [#1]  SMP
>> Modules linked in:
>> CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 7.3.0-rc2-7fb054f87+ #3627 PREEMPT(lazy) 
>> Hardware name: Generated (DT)
>> pstate: 1634023c9 (nZCv DAIF +ALLINT +PAN -UAO +TCO +DIT -SSBS BTYPE=--)
>> pc : 0xffff000970e81148
>> lr : 0xffff000970e81148
>> sp : ffff000970e81150
>> x29: ffff800080f85fc0 x28: 0000000000000001 x27: 0000000000002000
>> x26: 0000000000000000 x25: 00000000000000c0 x24: 0000000040000023
>> x23: ffff800080c0e1d8 x22: 00000000000003c0 x21: ffff800080b58300
>> x20: cfa2800080b58300 x19: 00000000200003c0 x18: 0000000000000000
>> x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000028
>> x14: 0000000000000000 x13: ffff8000814f3ac0 x12: ffff8008efcac000
>> x11: b2000c3eb474d99d x10: 0000000000000008 x9 : 0000000000001000
>> x8 : ffff800080010800 x7 : 055001f2b5503510 x6 : 0000000001310000
>> x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffff800081502d80
>> x2 : 0000000000000802 x1 : ffff000800106a70 x0 : 0000000000000001
>> Call trace:
>>  0xffff000970e81148 (P)
>> Code: 00000000 00000000 00000000 00000000 (00000002) 
>> ---[ end trace 0000000000000000 ]---
>> Kernel panic - not syncing: Oops: Fatal exception
>> SMP: stopping secondary CPUs
>> Kernel Offset: disabled
>> CPU features: 0x0,00000000,034bfc7d,ff728b42,7ffce667
>> Memory Limit: none
>> ---[ end Kernel panic - not syncing: Oops: Fatal exception ]---
>>
>> I suspect it is related to power management, since it can be triggered
>> with the sleep command, though I haven't debugged it. I noticed that
>> Sashiko has reported issues related to suspend/resume, so if you
>> provide fixups for the relevant commits, I can give them another
>> try. Otherwise, I'll wait for v2 :)
> It's fiddly to envisage how we end up trying to execute from non-executable
> memory, but there are two bugs in the suspend/resume code:
> 
> 1. I don't save/restore the stack pointers correctly (I suppose this could
>    explain almost any crash, tbh)
> 
> 2. I don't restore the pauth keys properly
> 
> I've hacked up an untested diff below, please can you take it for a spin?
> 

With fixup applied I do not see splat anymore :) 

Thanks
Vladimir

> Cheers,
> 
> Will
> 
> --->8
> 
> diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S
> index f093cdf71be1..facf3f1cc3b1 100644
> --- a/arch/arm64/kernel/sleep.S
> +++ b/arch/arm64/kernel/sleep.S
> @@ -133,7 +133,8 @@ SYM_FUNC_START(_cpu_resume)
>  	add	x0, x0, #SLEEP_STACK_DATA_SYSTEM_REGS
>  	/* load sp from context */
>  	ldr	x2, [x0, #CPU_CTX_SP]
> -	mov	sp, x2
> +	msr	sp_el0, x2
> +
>  	/*
>  	 * cpu_do_resume expects x0 to contain context address pointer
>  	 */
> diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
> index 0811fa569100..bec7f858fae9 100644
> --- a/arch/arm64/mm/proc.S
> +++ b/arch/arm64/mm/proc.S
> @@ -87,6 +87,7 @@
>   * This must be kept in sync with struct cpu_suspend_ctx in <asm/suspend.h>.
>   */
>  SYM_FUNC_START(cpu_do_suspend)
> +	msr	spsel, #1
>  	mrs	x2, tpidr_el0
>  	mrs	x3, tpidrro_el0
>  	mrs	x4, contextidr_el1
> @@ -98,8 +99,7 @@ SYM_FUNC_START(cpu_do_suspend)
>  	mrs	x10, oslsr_el1
>  	mrs	x11, sctlr_el1
>  	get_this_cpu_offset x12
> -	msr	spsel, #1
> -	mrs	x13, sp_el0
> +	mov	x13, sp				// SP_EL1
>  	stp	x2, x3, [x0]
>  	stp	x4, x5, [x0, #16]
>  	stp	x6, x7, [x0, #32]
> @@ -115,6 +115,7 @@ alternative_if ARM64_HAS_TCR2
>  	mrs	x2, REG_TCR2_EL1
>  	str	x2, [x0, #104]
>  alternative_else_nop_endif
> +	msr	spsel, #0
>  	ret
>  SYM_FUNC_END(cpu_do_suspend)
>  
> @@ -122,6 +123,8 @@ SYM_FUNC_END(cpu_do_suspend)
>   * cpu_do_resume - restore CPU register context
>   *
>   * x0: Address of context pointer
> + *
> + * Entered with SPSel == 1, returns with SPSel == 0.
>   */
>  SYM_FUNC_START(cpu_do_resume)
>  	ldp	x2, x3, [x0]
> @@ -130,6 +133,10 @@ SYM_FUNC_START(cpu_do_resume)
>  	ldp	x9, x10, [x0, #48]
>  	ldp	x11, x12, [x0, #64]
>  	ldp	x13, x14, [x0, #80]
> +
> +	/* Move 'current' somewhere safe */
> +	mov	x15, x3
> +
>  	/*
>  	 * Restore x18, as it may be used as a platform register, and clear
>  	 * the buffer to minimize the risk of exposure when used for shadow
> @@ -156,8 +163,7 @@ alternative_else_nop_endif
>  
>  	msr	sctlr_el1, x12
>  	set_this_cpu_offset x13
> -	msr	sp_el0, x14
> -	msr	spsel, #0
> +	mov	sp, x14				// SP_EL1
>  
>  	/*
>  	 * Restore oslsr_el1 by writing oslar_el1
> @@ -179,8 +185,9 @@ alternative_if ARM64_HAS_GIC_PRIO_MASKING
>  alternative_else_nop_endif
>  #endif
>  
> -	ptrauth_keys_install_kernel_nosync x14, x1, x2, x3
> +	ptrauth_keys_install_kernel_nosync x15, x1, x2, x3
>  	isb
> +	msr	spsel, #0
>  	ret
>  SYM_FUNC_END(cpu_do_resume)
>  #endif
>
Re: [PATCH 00/21] arm64: Move overflow sp into SP_EL1 and kernel sp into SP_EL0
Posted by Will Deacon 2 weeks ago
On Thu, Sep 10, 2026 at 02:49:37PM +0100, Vladimir Murzin wrote:
> On 9/9/26 12:29, Will Deacon wrote:
> > On Wed, Sep 09, 2026 at 11:39:24AM +0100, Vladimir Murzin wrote:
> > [...]
> > 
> >> I gave it a try and I observe splat:
>
> > I've hacked up an untested diff below, please can you take it for a spin?
> > 
> 
> With fixup applied I do not see splat anymore :) 

Excellent, thanks for testing it!

Will