summaryrefslogtreecommitdiff
path: root/lib/el3_runtime
diff options
context:
space:
mode:
authorAntonio Nino Diaz <antonio.ninodiaz@arm.com>2019-01-31 11:58:00 +0000
committerAntonio Nino Diaz <antonio.ninodiaz@arm.com>2019-02-27 11:08:59 +0000
commit5283962ebaf77850d68bb457608ede5174e43159 (patch)
tree28fbac607b59b0d21cdef870f74afa5a78f274d9 /lib/el3_runtime
parent4d1ccf0ecc7d90df438148c633291723d095f979 (diff)
Add ARMv8.3-PAuth registers to CPU context
ARMv8.3-PAuth adds functionality that supports address authentication of the contents of a register before that register is used as the target of an indirect branch, or as a load. This feature is supported only in AArch64 state. This feature is mandatory in ARMv8.3 implementations. This feature adds several registers to EL1. A new option called CTX_INCLUDE_PAUTH_REGS has been added to select if the TF needs to save them during Non-secure <-> Secure world switches. This option must be enabled if the hardware has the registers or the values will be leaked during world switches. To prevent leaks, this patch also disables pointer authentication in the Secure world if CTX_INCLUDE_PAUTH_REGS is 0. Any attempt to use it will be trapped in EL3. Change-Id: I27beba9907b9a86c6df1d0c5bf6180c972830855 Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
Diffstat (limited to 'lib/el3_runtime')
-rw-r--r--lib/el3_runtime/aarch64/context.S79
-rw-r--r--lib/el3_runtime/aarch64/context_mgmt.c14
2 files changed, 93 insertions, 0 deletions
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 1f8e23d2..f5fed72d 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -14,6 +14,10 @@
.global fpregs_context_save
.global fpregs_context_restore
#endif
+#if CTX_INCLUDE_PAUTH_REGS
+ .global pauth_context_restore
+ .global pauth_context_save
+#endif
.global save_gp_registers
.global restore_gp_registers
.global restore_gp_registers_eret
@@ -299,6 +303,76 @@ func fpregs_context_restore
endfunc fpregs_context_restore
#endif /* CTX_INCLUDE_FPREGS */
+#if CTX_INCLUDE_PAUTH_REGS
+/* -----------------------------------------------------
+ * The following function strictly follows the AArch64
+ * PCS to use x9-x17 (temporary caller-saved registers)
+ * to save the ARMv8.3-PAuth register context. It assumes
+ * that 'sp' is pointing to a 'cpu_context_t' structure
+ * to where the register context will be saved.
+ * -----------------------------------------------------
+ */
+func pauth_context_save
+ add x11, sp, #CTX_PAUTH_REGS_OFFSET
+
+ mrs x9, APIAKeyLo_EL1
+ mrs x10, APIAKeyHi_EL1
+ stp x9, x10, [x11, #CTX_PACIAKEY_LO]
+
+ mrs x9, APIBKeyLo_EL1
+ mrs x10, APIBKeyHi_EL1
+ stp x9, x10, [x11, #CTX_PACIBKEY_LO]
+
+ mrs x9, APDAKeyLo_EL1
+ mrs x10, APDAKeyHi_EL1
+ stp x9, x10, [x11, #CTX_PACDAKEY_LO]
+
+ mrs x9, APDBKeyLo_EL1
+ mrs x10, APDBKeyHi_EL1
+ stp x9, x10, [x11, #CTX_PACDBKEY_LO]
+
+ mrs x9, APGAKeyLo_EL1
+ mrs x10, APGAKeyHi_EL1
+ stp x9, x10, [x11, #CTX_PACGAKEY_LO]
+
+ ret
+endfunc pauth_context_save
+
+/* -----------------------------------------------------
+ * The following function strictly follows the AArch64
+ * PCS to use x9-x17 (temporary caller-saved registers)
+ * to restore the ARMv8.3-PAuth register context. It assumes
+ * that 'sp' is pointing to a 'cpu_context_t' structure
+ * from where the register context will be restored.
+ * -----------------------------------------------------
+ */
+func pauth_context_restore
+ add x11, sp, #CTX_PAUTH_REGS_OFFSET
+
+ ldp x9, x10, [x11, #CTX_PACIAKEY_LO]
+ msr APIAKeyLo_EL1, x9
+ msr APIAKeyHi_EL1, x10
+
+ ldp x9, x10, [x11, #CTX_PACIAKEY_LO]
+ msr APIBKeyLo_EL1, x9
+ msr APIBKeyHi_EL1, x10
+
+ ldp x9, x10, [x11, #CTX_PACDAKEY_LO]
+ msr APDAKeyLo_EL1, x9
+ msr APDAKeyHi_EL1, x10
+
+ ldp x9, x10, [x11, #CTX_PACDBKEY_LO]
+ msr APDBKeyLo_EL1, x9
+ msr APDBKeyHi_EL1, x10
+
+ ldp x9, x10, [x11, #CTX_PACGAKEY_LO]
+ msr APGAKeyLo_EL1, x9
+ msr APGAKeyHi_EL1, x10
+
+ ret
+endfunc pauth_context_restore
+#endif /* CTX_INCLUDE_PAUTH_REGS */
+
/* -----------------------------------------------------
* The following functions are used to save and restore
* all the general purpose registers. Ideally we would
@@ -415,6 +489,11 @@ func el3_exit
1:
#endif
+#if CTX_INCLUDE_PAUTH_REGS
+ /* Restore ARMv8.3-PAuth registers */
+ bl pauth_context_restore
+#endif
+
/* Restore saved general purpose registers and return */
b restore_gp_registers_eret
endfunc el3_exit
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index b956491e..83f6e489 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -122,6 +122,20 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep)
scr_el3 |= SCR_FIEN_BIT;
#endif
+#if !CTX_INCLUDE_PAUTH_REGS
+ /*
+ * If the pointer authentication registers aren't saved during world
+ * switches the value of the registers can be leaked from the Secure to
+ * the Non-secure world. To prevent this, rather than enabling pointer
+ * authentication everywhere, we only enable it in the Non-secure world.
+ *
+ * If the Secure world wants to use pointer authentication,
+ * CTX_INCLUDE_PAUTH_REGS must be set to 1.
+ */
+ if (security_state == NON_SECURE)
+ scr_el3 |= SCR_API_BIT | SCR_APK_BIT;
+#endif /* !CTX_INCLUDE_PAUTH_REGS */
+
#ifdef IMAGE_BL31
/*
* SCR_EL3.IRQ, SCR_EL3.FIQ: Enable the physical FIQ and IRQ routing as