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 <jwerner@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/89926
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
This commit is contained in:
Julius Werner 2025-11-05 16:53:30 -08:00 committed by Yu-Ping Wu
commit 84e000b88e
2 changed files with 6 additions and 3 deletions

View file

@ -30,7 +30,7 @@
#include <libpayload.h>
#include <stdint.h>
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" },

View file

@ -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)
{