From 84e000b88e7fe8bec57201766fab496cbdb9ac24 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Wed, 5 Nov 2025 16:53:30 -0800 Subject: [PATCH] libpayload: arm64: Fix alignment for exception_state In the arm64 exception handler in libpayload, we use the banked exception stack pointer (SP_EL2, as opposed to the normal SP_EL0) not as a normal stack pointer, but simply as a pointer to the exception_state struct. This makes it easy to dump all registers into that struct on context switch. We then immediately switch back to SP_EL0. Yet, even though it is not really a stack for us, the aarch64 architecture still requires that SP_EL2 is 16 byte aligned at function boundaries. If the exception_state struct is not thus aligned, exceptions are broken. (I don't know why nobody ever hit this before, but I hit it now while trying to pull in zstd code. I guess we just don't have unaligned BSS entries that often and simply got lucky for a while. 3 hours wasted on debugging. :( ) Change-Id: Id19184656fb9da68fe4bfdbc240c0c25b9d24cd6 Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/89926 Tested-by: build bot (Jenkins) Reviewed-by: Yu-Ping Wu --- payloads/libpayload/arch/arm64/exception.c | 7 +++++-- payloads/libpayload/arch/arm64/gdb.c | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/payloads/libpayload/arch/arm64/exception.c b/payloads/libpayload/arch/arm64/exception.c index 21ed1c2661..3a9157f4f4 100644 --- a/payloads/libpayload/arch/arm64/exception.c +++ b/payloads/libpayload/arch/arm64/exception.c @@ -30,7 +30,7 @@ #include #include -u64 exception_stack[2*KiB] __attribute__((aligned(16))); +u64 exception_stack[2*KiB] __aligned(16); u64 *exception_stack_end = exception_stack + ARRAY_SIZE(exception_stack); struct exception_handler_info @@ -39,7 +39,10 @@ struct exception_handler_info }; static exception_hook hook; -struct exception_state exception_state; + +/* To make the exception entry easier, we write this into SP_EL2. AArch64 demands + that stack pointers are always 16-byte aligned at function boundaries. */ +struct exception_state exception_state __aligned(16); static struct exception_handler_info exceptions[EXC_COUNT] = { [EXC_SYNC_SP0] = { "_sync_sp_el0" }, diff --git a/payloads/libpayload/arch/arm64/gdb.c b/payloads/libpayload/arch/arm64/gdb.c index 10ae675fe4..230f2a9e45 100644 --- a/payloads/libpayload/arch/arm64/gdb.c +++ b/payloads/libpayload/arch/arm64/gdb.c @@ -32,7 +32,7 @@ struct gdb_regs } __packed; /* Scratch value to write reentrant exception states to. We never read it. */ -static struct exception_state sentinel_exception_state; +static struct exception_state sentinel_exception_state __aligned(16); static int gdb_exception_hook(u32 type) {