From fb0e4b18430e4e0a9c61bae7aa644ed6b7248c11 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Wed, 11 Dec 2024 12:17:42 -0500 Subject: [PATCH] arm64: Avoid clobbering the stack pointer when returning to EL1 We use x18 as a temp register but in hybrid kernels this is clobbered when restoring callee-saved registers. --- sys/arm64/arm64/exception.S | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sys/arm64/arm64/exception.S b/sys/arm64/arm64/exception.S index 25cfeaeee99e..c39fe0fd3a9a 100644 --- a/sys/arm64/arm64/exception.S +++ b/sys/arm64/arm64/exception.S @@ -181,7 +181,17 @@ * registers so must always do this. */ #endif +.if \el == 1 + /* + * In the kernel, x18 is always used as the per-CPU data pointer and is + * reset to the value in tpidr_el1 further below. At this point when + * returning to EL1, x18 contains the saved stack pointer, so be careful + * not to clobber it. + */ + ldr CAP(19), [PTRN(sp), #(TF_X + 19 * CAP_WIDTH)] +.else ldp CAP(18), CAP(19), [PTRN(sp), #(TF_X + 18 * CAP_WIDTH)] +.endif ldp CAP(20), CAP(21), [PTRN(sp), #(TF_X + 20 * CAP_WIDTH)] ldp CAP(22), CAP(23), [PTRN(sp), #(TF_X + 22 * CAP_WIDTH)] ldp CAP(24), CAP(25), [PTRN(sp), #(TF_X + 24 * CAP_WIDTH)]