fix: add xpaci instruction to exception report
When reporting an exception with ENABLE_PAUTH==1 calling xpaci
before printing the ELR value will remove the PAC and make the
pointer readable.
Change-Id: I45339dbb3396f403768ea3ee780d0c5010da44c4
Signed-off-by: John Powell <john.powell@arm.com>
diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h
index 35d2454..e6b588f 100644
--- a/include/lib/aarch64/arch_helpers.h
+++ b/include/lib/aarch64/arch_helpers.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -231,6 +231,8 @@
DEFINE_SYSOP_PARAM_FUNC(wfit)
DEFINE_SYSOP_PARAM_FUNC(wfet)
+DEFINE_SYSOP_PARAM_FUNC(xpaci)
+
DEFINE_RENAME_SYSREG_RW_FUNCS(sys_accdata_el1, SYS_ACCDATA_EL1)
static inline void enable_irq(void)
diff --git a/tftf/framework/aarch64/exception_report.c b/tftf/framework/aarch64/exception_report.c
index 0add276..48ccefe 100644
--- a/tftf/framework/aarch64/exception_report.c
+++ b/tftf/framework/aarch64/exception_report.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2025, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -31,6 +31,8 @@
void __dead2 print_exception(const struct cpu_context *ctx)
{
u_register_t mpid = read_mpidr_el1();
+ uintptr_t elr = read_sysreg(elr);
+ uintptr_t lr = ctx->regs[30]; /* LR is x30 */
/*
* The instruction barrier ensures we don't read stale values of system
@@ -38,13 +40,19 @@
*/
isb();
+#if ENABLE_PAUTH
+ /* If PAUTH enabled then remove PAC from ELR and LR with xpaci. */
+ xpaci(elr);
+ xpaci(lr);
+#endif /* ENABLE_PAUTH */
+
printf("Unhandled exception on CPU%u.\n", platform_get_core_pos(mpid));
/* Dump some interesting system registers. */
printf("System registers:\n");
printf(" MPIDR=0x%lx\n", mpid);
printf(" ESR=0x%lx ELR=0x%lx FAR=0x%lx\n", read_sysreg(esr),
- read_sysreg(elr), read_sysreg(far));
+ elr, read_sysreg(far));
printf(" SCTLR=0x%lx SPSR=0x%lx DAIF=0x%lx\n",
read_sysreg(sctlr), read_sysreg(spsr), read_daif());
@@ -53,6 +61,7 @@
for (int i = 0; i < GPREGS_CNT; ++i) {
printf(" x%u=0x%lx\n", i, ctx->regs[i]);
}
+ printf(" LR=0x%lx\n", lr);
printf(" SP=0x%lx\n", ctx->sp);
while (1)