Commit ed108b56 authored by Alexei Fedorov's avatar Alexei Fedorov
Browse files

Refactor ARMv8.3 Pointer Authentication support code



This patch provides the following features and makes modifications
listed below:
- Individual APIAKey key generation for each CPU.
- New key generation on every BL31 warm boot and TSP CPU On event.
- Per-CPU storage of APIAKey added in percpu_data[]
  of cpu_data structure.
- `plat_init_apiakey()` function replaced with `plat_init_apkey()`
  which returns 128-bit value and uses Generic timer physical counter
  value to increase the randomness of the generated key.
  The new function can be used for generation of all ARMv8.3-PAuth keys
- ARMv8.3-PAuth specific code placed in `lib\extensions\pauth`.
- New `pauth_init_enable_el1()` and `pauth_init_enable_el3()` functions
  generate, program and enable APIAKey_EL1 for EL1 and EL3 respectively;
  pauth_disable_el1()` and `pauth_disable_el3()` functions disable
  PAuth for EL1 and EL3 respectively;
  `pauth_load_bl31_apiakey()` loads saved per-CPU APIAKey_EL1 from
  cpu-data structure.
- Combined `save_gp_pauth_registers()` function replaces calls to
  `save_gp_registers()` and `pauth_context_save()`;
  `restore_gp_pauth_registers()` replaces `pauth_context_restore()`
  and `restore_gp_registers()` calls.
- `restore_gp_registers_eret()` function removed with corresponding
  code placed in `el3_exit()`.
- Fixed the issue when `pauth_t pauth_ctx` structure allocated space
  for 12 uint64_t PAuth registers instead of 10 by removal of macro
  CTX_PACGAKEY_END from `include/lib/el3_runtime/aarch64/context.h`
  and assigning its value to CTX_PAUTH_REGS_END.
- Use of MODE_SP_ELX and MODE_SP_EL0 macro definitions
  in `msr	spsel`  instruction instead of hard-coded values.
- Changes in documentation related to ARMv8.3-PAuth and ARMv8.5-BTI.

Change-Id: Id18b81cc46f52a783a7e6a09b9f149b6ce803211
Signed-off-by: default avatarAlexei Fedorov <Alexei.Fedorov@arm.com>
parent 2fc6ffc4
...@@ -38,15 +38,12 @@ func bl1_entrypoint ...@@ -38,15 +38,12 @@ func bl1_entrypoint
*/ */
bl bl1_setup bl bl1_setup
#if ENABLE_PAUTH
/* -------------------------------------------------------------------- /* --------------------------------------------------------------------
* Enable pointer authentication * Program APIAKey_EL1 and enable pointer authentication.
* -------------------------------------------------------------------- * --------------------------------------------------------------------
*/ */
#if ENABLE_PAUTH bl pauth_init_enable_el3
mrs x0, sctlr_el3
orr x0, x0, #SCTLR_EnIA_BIT
msr sctlr_el3, x0
isb
#endif /* ENABLE_PAUTH */ #endif /* ENABLE_PAUTH */
/* -------------------------------------------------------------------- /* --------------------------------------------------------------------
...@@ -56,16 +53,12 @@ func bl1_entrypoint ...@@ -56,16 +53,12 @@ func bl1_entrypoint
*/ */
bl bl1_main bl bl1_main
#if ENABLE_PAUTH
/* -------------------------------------------------------------------- /* --------------------------------------------------------------------
* Disable pointer authentication before jumping to BL31 or that will * Disable pointer authentication before jumping to next boot image.
* cause an authentication failure during the early platform init.
* -------------------------------------------------------------------- * --------------------------------------------------------------------
*/ */
#if ENABLE_PAUTH bl pauth_disable_el3
mrs x0, sctlr_el3
bic x0, x0, #SCTLR_EnIA_BIT
msr sctlr_el3, x0
isb
#endif /* ENABLE_PAUTH */ #endif /* ENABLE_PAUTH */
/* -------------------------------------------------- /* --------------------------------------------------
......
...@@ -164,7 +164,7 @@ func smc_handler64 ...@@ -164,7 +164,7 @@ func smc_handler64
* ---------------------------------------------- * ----------------------------------------------
*/ */
ldr x30, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP] ldr x30, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
msr spsel, #0 msr spsel, #MODE_SP_EL0
mov sp, x30 mov sp, x30
/* --------------------------------------------------------------------- /* ---------------------------------------------------------------------
...@@ -217,19 +217,14 @@ unexpected_sync_exception: ...@@ -217,19 +217,14 @@ unexpected_sync_exception:
*/ */
smc_handler: smc_handler:
/* ----------------------------------------------------- /* -----------------------------------------------------
* Save the GP registers x0-x29. * Save x0-x29 and ARMv8.3-PAuth (if enabled) registers.
* TODO: Revisit to store only SMCCC specified registers.
* -----------------------------------------------------
*/
bl save_gp_registers
/* -----------------------------------------------------
* If Secure Cycle Counter is not disabled in MDCR_EL3 * If Secure Cycle Counter is not disabled in MDCR_EL3
* when ARMv8.5-PMU is implemented, save PMCR_EL0 and * when ARMv8.5-PMU is implemented, save PMCR_EL0 and
* disable all event counters and cycle counter. * disable Cycle Counter.
* TODO: Revisit to store only SMCCC specified registers.
* ----------------------------------------------------- * -----------------------------------------------------
*/ */
bl save_pmcr_disable_pmu bl save_gp_pmcr_pauth_regs
/* ----------------------------------------------------- /* -----------------------------------------------------
* Populate the parameters for the SMC handler. We * Populate the parameters for the SMC handler. We
...@@ -255,7 +250,7 @@ smc_handler: ...@@ -255,7 +250,7 @@ smc_handler:
* Switch back to SP_EL0 for the C runtime stack. * Switch back to SP_EL0 for the C runtime stack.
* --------------------------------------------- * ---------------------------------------------
*/ */
msr spsel, #0 msr spsel, #MODE_SP_EL0
mov sp, x12 mov sp, x12
/* ----------------------------------------------------- /* -----------------------------------------------------
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <platform_def.h> #include <platform_def.h>
#include <arch.h> #include <arch.h>
#include <arch_features.h>
#include <arch_helpers.h> #include <arch_helpers.h>
#include <bl1/bl1.h> #include <bl1/bl1.h>
#include <common/bl_common.h> #include <common/bl_common.h>
...@@ -59,18 +60,16 @@ void bl1_setup(void) ...@@ -59,18 +60,16 @@ void bl1_setup(void)
/* Perform early platform-specific setup */ /* Perform early platform-specific setup */
bl1_early_platform_setup(); bl1_early_platform_setup();
#ifdef __aarch64__
/*
* Update pointer authentication key before the MMU is enabled. It is
* saved in the rodata section, that can be writen before enabling the
* MMU. This function must be called after the console is initialized
* in the early platform setup.
*/
bl_handle_pauth();
#endif /* __aarch64__ */
/* Perform late platform-specific setup */ /* Perform late platform-specific setup */
bl1_plat_arch_setup(); bl1_plat_arch_setup();
#if CTX_INCLUDE_PAUTH_REGS
/*
* Assert that the ARMv8.3-PAuth registers are present or an access
* fault will be triggered when they are being saved or restored.
*/
assert(is_armv8_3_pauth_present());
#endif /* CTX_INCLUDE_PAUTH_REGS */
} }
/******************************************************************************* /*******************************************************************************
......
...@@ -43,22 +43,12 @@ func bl2_entrypoint ...@@ -43,22 +43,12 @@ func bl2_entrypoint
*/ */
bl bl2_el3_setup bl bl2_el3_setup
/* ---------------------------------------------
* Enable pointer authentication
* ---------------------------------------------
*/
#if ENABLE_PAUTH #if ENABLE_PAUTH
mrs x0, sctlr_el3
orr x0, x0, #SCTLR_EnIA_BIT
#if ENABLE_BTI
/* --------------------------------------------- /* ---------------------------------------------
* Enable PAC branch type compatibility * Program APIAKey_EL1 and enable pointer authentication.
* --------------------------------------------- * ---------------------------------------------
*/ */
bic x0, x0, #SCTLR_BT_BIT bl pauth_init_enable_el3
#endif /* ENABLE_BTI */
msr sctlr_el3, x0
isb
#endif /* ENABLE_PAUTH */ #endif /* ENABLE_PAUTH */
/* --------------------------------------------- /* ---------------------------------------------
...@@ -87,16 +77,13 @@ func bl2_run_next_image ...@@ -87,16 +77,13 @@ func bl2_run_next_image
tlbi alle3 tlbi alle3
bl bl2_el3_plat_prepare_exit bl bl2_el3_plat_prepare_exit
#if ENABLE_PAUTH
/* --------------------------------------------- /* ---------------------------------------------
* Disable pointer authentication before jumping to BL31 or that will * Disable pointer authentication before jumping
* cause an authentication failure during the early platform init. * to next boot image.
* --------------------------------------------- * ---------------------------------------------
*/ */
#if ENABLE_PAUTH bl pauth_disable_el3
mrs x0, sctlr_el3
bic x0, x0, #SCTLR_EnIA_BIT
msr sctlr_el3, x0
isb
#endif /* ENABLE_PAUTH */ #endif /* ENABLE_PAUTH */
ldp x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET] ldp x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET]
......
...@@ -117,22 +117,13 @@ func bl2_entrypoint ...@@ -117,22 +117,13 @@ func bl2_entrypoint
mov x3, x23 mov x3, x23
bl bl2_setup bl bl2_setup
/* ---------------------------------------------
* Enable pointer authentication
* ---------------------------------------------
*/
#if ENABLE_PAUTH #if ENABLE_PAUTH
mrs x0, sctlr_el1
orr x0, x0, #SCTLR_EnIA_BIT
#if ENABLE_BTI
/* --------------------------------------------- /* ---------------------------------------------
* Enable PAC branch type compatibility * Program APIAKey_EL1
* and enable pointer authentication.
* --------------------------------------------- * ---------------------------------------------
*/ */
bic x0, x0, #(SCTLR_BT0_BIT | SCTLR_BT1_BIT) bl pauth_init_enable_el1
#endif /* ENABLE_BTI */
msr sctlr_el1, x0
isb
#endif /* ENABLE_PAUTH */ #endif /* ENABLE_PAUTH */
/* --------------------------------------------- /* ---------------------------------------------
......
...@@ -4,13 +4,17 @@ ...@@ -4,13 +4,17 @@
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
#include <assert.h>
#include <arch_helpers.h> #include <arch_helpers.h>
#include <arch_features.h>
#include <bl1/bl1.h> #include <bl1/bl1.h>
#include <bl2/bl2.h> #include <bl2/bl2.h>
#include <common/bl_common.h> #include <common/bl_common.h>
#include <common/debug.h> #include <common/debug.h>
#include <drivers/auth/auth_mod.h> #include <drivers/auth/auth_mod.h>
#include <drivers/console.h> #include <drivers/console.h>
#include <lib/extensions/pauth.h>
#include <plat/common/platform.h> #include <plat/common/platform.h>
#include "bl2_private.h" #include "bl2_private.h"
...@@ -31,18 +35,16 @@ void bl2_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, ...@@ -31,18 +35,16 @@ void bl2_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
/* Perform early platform-specific setup */ /* Perform early platform-specific setup */
bl2_early_platform_setup2(arg0, arg1, arg2, arg3); bl2_early_platform_setup2(arg0, arg1, arg2, arg3);
#ifdef __aarch64__
/*
* Update pointer authentication key before the MMU is enabled. It is
* saved in the rodata section, that can be writen before enabling the
* MMU. This function must be called after the console is initialized
* in the early platform setup.
*/
bl_handle_pauth();
#endif /* __aarch64__ */
/* Perform late platform-specific setup */ /* Perform late platform-specific setup */
bl2_plat_arch_setup(); bl2_plat_arch_setup();
#if CTX_INCLUDE_PAUTH_REGS
/*
* Assert that the ARMv8.3-PAuth registers are present or an access
* fault will be triggered when they are being saved or restored.
*/
assert(is_armv8_3_pauth_present());
#endif /* CTX_INCLUDE_PAUTH_REGS */
} }
#else /* if BL2_AT_EL3 */ #else /* if BL2_AT_EL3 */
...@@ -55,18 +57,16 @@ void bl2_el3_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, ...@@ -55,18 +57,16 @@ void bl2_el3_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
/* Perform early platform-specific setup */ /* Perform early platform-specific setup */
bl2_el3_early_platform_setup(arg0, arg1, arg2, arg3); bl2_el3_early_platform_setup(arg0, arg1, arg2, arg3);
#ifdef __aarch64__
/*
* Update pointer authentication key before the MMU is enabled. It is
* saved in the rodata section, that can be writen before enabling the
* MMU. This function must be called after the console is initialized
* in the early platform setup.
*/
bl_handle_pauth();
#endif /* __aarch64__ */
/* Perform late platform-specific setup */ /* Perform late platform-specific setup */
bl2_el3_plat_arch_setup(); bl2_el3_plat_arch_setup();
#if CTX_INCLUDE_PAUTH_REGS
/*
* Assert that the ARMv8.3-PAuth registers are present or an access
* fault will be triggered when they are being saved or restored.
*/
assert(is_armv8_3_pauth_present());
#endif /* CTX_INCLUDE_PAUTH_REGS */
} }
#endif /* BL2_AT_EL3 */ #endif /* BL2_AT_EL3 */
...@@ -108,6 +108,13 @@ void bl2_main(void) ...@@ -108,6 +108,13 @@ void bl2_main(void)
console_flush(); console_flush();
#if ENABLE_PAUTH
/*
* Disable pointer authentication before running next boot image
*/
pauth_disable_el1();
#endif /* ENABLE_PAUTH */
/* /*
* Run next BL image via an SMC to BL1. Information on how to pass * Run next BL image via an SMC to BL1. Information on how to pass
* control to the BL32 (if present) and BL33 software images will * control to the BL32 (if present) and BL33 software images will
...@@ -119,6 +126,13 @@ void bl2_main(void) ...@@ -119,6 +126,13 @@ void bl2_main(void)
print_entry_point_info(next_bl_ep_info); print_entry_point_info(next_bl_ep_info);
console_flush(); console_flush();
#if ENABLE_PAUTH
/*
* Disable pointer authentication before running next boot image
*/
pauth_disable_el3();
#endif /* ENABLE_PAUTH */
bl2_run_next_image(next_bl_ep_info); bl2_run_next_image(next_bl_ep_info);
#endif /* BL2_AT_EL3 */ #endif /* BL2_AT_EL3 */
} }
...@@ -98,26 +98,16 @@ func bl31_entrypoint ...@@ -98,26 +98,16 @@ func bl31_entrypoint
mov x3, x23 mov x3, x23
bl bl31_setup bl bl31_setup
/* --------------------------------------------------------------------
* Enable pointer authentication
* --------------------------------------------------------------------
*/
#if ENABLE_PAUTH #if ENABLE_PAUTH
mrs x0, sctlr_el3
orr x0, x0, #SCTLR_EnIA_BIT
#if ENABLE_BTI
/* -------------------------------------------------------------------- /* --------------------------------------------------------------------
* Enable PAC branch type compatibility * Program APIAKey_EL1 and enable pointer authentication
* -------------------------------------------------------------------- * --------------------------------------------------------------------
*/ */
bic x0, x0, #SCTLR_BT_BIT bl pauth_init_enable_el3
#endif /* ENABLE_BTI */
msr sctlr_el3, x0
isb
#endif /* ENABLE_PAUTH */ #endif /* ENABLE_PAUTH */
/* -------------------------------------------------------------------- /* --------------------------------------------------------------------
* Jump to main function. * Jump to main function
* -------------------------------------------------------------------- * --------------------------------------------------------------------
*/ */
bl bl31_main bl bl31_main
...@@ -209,24 +199,12 @@ func bl31_warm_entrypoint ...@@ -209,24 +199,12 @@ func bl31_warm_entrypoint
#endif #endif
bl bl31_plat_enable_mmu bl bl31_plat_enable_mmu
/* --------------------------------------------------------------------
* Enable pointer authentication
* --------------------------------------------------------------------
*/
#if ENABLE_PAUTH #if ENABLE_PAUTH
bl pauth_load_bl_apiakey
mrs x0, sctlr_el3
orr x0, x0, #SCTLR_EnIA_BIT
#if ENABLE_BTI
/* -------------------------------------------------------------------- /* --------------------------------------------------------------------
* Enable PAC branch type compatibility * Program APIAKey_EL1 and enable pointer authentication
* -------------------------------------------------------------------- * --------------------------------------------------------------------
*/ */
bic x0, x0, #SCTLR_BT_BIT bl pauth_init_enable_el3
#endif /* ENABLE_BTI */
msr sctlr_el3, x0
isb
#endif /* ENABLE_PAUTH */ #endif /* ENABLE_PAUTH */
bl psci_warmboot_entrypoint bl psci_warmboot_entrypoint
......
...@@ -65,22 +65,16 @@ func enter_lower_el_sync_ea ...@@ -65,22 +65,16 @@ func enter_lower_el_sync_ea
mrs x30, esr_el3 mrs x30, esr_el3
tbz x30, #ESR_ISS_EABORT_EA_BIT, 2f tbz x30, #ESR_ISS_EABORT_EA_BIT, 2f
/* Save GP registers */
bl save_gp_registers
/* /*
* If Secure Cycle Counter is not disabled in MDCR_EL3 * Save general purpose and ARMv8.3-PAuth registers (if enabled).
* when ARMv8.5-PMU is implemented, save PMCR_EL0 and * If Secure Cycle Counter is not disabled in MDCR_EL3 when
* disable all event counters and cycle counter. * ARMv8.5-PMU is implemented, save PMCR_EL0 and disable Cycle Counter.
*/ */
bl save_pmcr_disable_pmu bl save_gp_pmcr_pauth_regs
/* Save ARMv8.3-PAuth registers and load firmware key */
#if CTX_INCLUDE_PAUTH_REGS
bl pauth_context_save
#endif
#if ENABLE_PAUTH #if ENABLE_PAUTH
bl pauth_load_bl_apiakey /* Load and program APIAKey firmware key */
bl pauth_load_bl31_apiakey
#endif #endif
/* Setup exception class and syndrome arguments for platform handler */ /* Setup exception class and syndrome arguments for platform handler */
...@@ -110,22 +104,16 @@ func enter_lower_el_async_ea ...@@ -110,22 +104,16 @@ func enter_lower_el_async_ea
*/ */
str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
/* Save GP registers */
bl save_gp_registers
/* /*
* If Secure Cycle Counter is not disabled in MDCR_EL3 * Save general purpose and ARMv8.3-PAuth registers (if enabled).
* when ARMv8.5-PMU is implemented, save PMCR_EL0 and * If Secure Cycle Counter is not disabled in MDCR_EL3 when
* disable all event counters and cycle counter. * ARMv8.5-PMU is implemented, save PMCR_EL0 and disable Cycle Counter.
*/ */
bl save_pmcr_disable_pmu bl save_gp_pmcr_pauth_regs
/* Save ARMv8.3-PAuth registers and load firmware key */
#if CTX_INCLUDE_PAUTH_REGS
bl pauth_context_save
#endif
#if ENABLE_PAUTH #if ENABLE_PAUTH
bl pauth_load_bl_apiakey /* Load and program APIAKey firmware key */
bl pauth_load_bl31_apiakey
#endif #endif
/* Setup exception class and syndrome arguments for platform handler */ /* Setup exception class and syndrome arguments for platform handler */
...@@ -247,7 +235,7 @@ func ea_proceed ...@@ -247,7 +235,7 @@ func ea_proceed
/* Switch to runtime stack */ /* Switch to runtime stack */
ldr x5, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP] ldr x5, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
msr spsel, #0 msr spsel, #MODE_SP_EL0
mov sp, x5 mov sp, x5
mov x29, x30 mov x29, x30
...@@ -269,7 +257,7 @@ func ea_proceed ...@@ -269,7 +257,7 @@ func ea_proceed
#endif #endif
/* Make SP point to context */ /* Make SP point to context */
msr spsel, #1 msr spsel, #MODE_SP_ELX
/* Restore EL3 state and ESR */ /* Restore EL3 state and ESR */
ldp x1, x2, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3] ldp x1, x2, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
......
...@@ -65,19 +65,17 @@ ...@@ -65,19 +65,17 @@
mrs x30, DISR_EL1 mrs x30, DISR_EL1
tbz x30, #DISR_A_BIT, 1f tbz x30, #DISR_A_BIT, 1f
/* Save GP registers and restore them afterwards */
bl save_gp_registers
/* /*
* If Secure Cycle Counter is not disabled in MDCR_EL3 * Save general purpose and ARMv8.3-PAuth registers (if enabled).
* when ARMv8.5-PMU is implemented, save PMCR_EL0 and * If Secure Cycle Counter is not disabled in MDCR_EL3 when
* disable all event counters and cycle counter. * ARMv8.5-PMU is implemented, save PMCR_EL0 and disable Cycle Counter.
*/ */
bl save_pmcr_disable_pmu bl save_gp_pmcr_pauth_regs
bl handle_lower_el_ea_esb bl handle_lower_el_ea_esb
bl restore_gp_registers
/* Restore general purpose, PMCR_EL0 and ARMv8.3-PAuth registers */
bl restore_gp_pmcr_pauth_regs
1: 1:
#else #else
/* Unmask the SError interrupt */ /* Unmask the SError interrupt */
...@@ -129,21 +127,16 @@ ...@@ -129,21 +127,16 @@
*/ */
.macro handle_interrupt_exception label .macro handle_interrupt_exception label
bl save_gp_registers
/* /*
* If Secure Cycle Counter is not disabled in MDCR_EL3 * Save general purpose and ARMv8.3-PAuth registers (if enabled).
* when ARMv8.5-PMU is implemented, save PMCR_EL0 and * If Secure Cycle Counter is not disabled in MDCR_EL3 when
* disable all event counters and cycle counter. * ARMv8.5-PMU is implemented, save PMCR_EL0 and disable Cycle Counter.
*/ */
bl save_pmcr_disable_pmu bl save_gp_pmcr_pauth_regs
/* Save ARMv8.3-PAuth registers and load firmware key */
#if CTX_INCLUDE_PAUTH_REGS
bl pauth_context_save
#endif
#if ENABLE_PAUTH #if ENABLE_PAUTH
bl pauth_load_bl_apiakey /* Load and program APIAKey firmware key */
bl pauth_load_bl31_apiakey
#endif #endif
/* Save the EL3 system registers needed to return from this exception */ /* Save the EL3 system registers needed to return from this exception */
...@@ -154,7 +147,7 @@ ...@@ -154,7 +147,7 @@
/* Switch to the runtime stack i.e. SP_EL0 */ /* Switch to the runtime stack i.e. SP_EL0 */
ldr x2, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP] ldr x2, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
mov x20, sp mov x20, sp
msr spsel, #0 msr spsel, #MODE_SP_EL0
mov sp, x2 mov sp, x2
/* /*
...@@ -368,22 +361,16 @@ smc_handler32: ...@@ -368,22 +361,16 @@ smc_handler32:
smc_handler64: smc_handler64:
/* NOTE: The code below must preserve x0-x4 */ /* NOTE: The code below must preserve x0-x4 */
/* Save general purpose registers */
bl save_gp_registers
/* /*
* If Secure Cycle Counter is not disabled in MDCR_EL3 * Save general purpose and ARMv8.3-PAuth registers (if enabled).
* when ARMv8.5-PMU is implemented, save PMCR_EL0 and * If Secure Cycle Counter is not disabled in MDCR_EL3 when
* disable all event counters and cycle counter. * ARMv8.5-PMU is implemented, save PMCR_EL0 and disable Cycle Counter.
*/ */
bl save_pmcr_disable_pmu bl save_gp_pmcr_pauth_regs
/* Save ARMv8.3-PAuth registers and load firmware key */
#if CTX_INCLUDE_PAUTH_REGS
bl pauth_context_save
#endif
#if ENABLE_PAUTH #if ENABLE_PAUTH
bl pauth_load_bl_apiakey /* Load and program APIAKey firmware key */
bl pauth_load_bl31_apiakey
#endif #endif
/* /*
...@@ -403,7 +390,7 @@ smc_handler64: ...@@ -403,7 +390,7 @@ smc_handler64:
ldr x12, [x6, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP] ldr x12, [x6, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
/* Switch to SP_EL0 */ /* Switch to SP_EL0 */
msr spsel, #0 msr spsel, #MODE_SP_EL0
/* /*
* Save the SPSR_EL3, ELR_EL3, & SCR_EL3 in case there is a world * Save the SPSR_EL3, ELR_EL3, & SCR_EL3 in case there is a world
...@@ -471,10 +458,12 @@ smc_prohibited: ...@@ -471,10 +458,12 @@ smc_prohibited:
mov x0, #SMC_UNK mov x0, #SMC_UNK
eret eret
#if DEBUG
rt_svc_fw_critical_error: rt_svc_fw_critical_error:
/* Switch to SP_ELx */ /* Switch to SP_ELx */
msr spsel, #1 msr spsel, #MODE_SP_ELX
no_ret report_unhandled_exception no_ret report_unhandled_exception
#endif
endfunc smc_handler endfunc smc_handler
/* --------------------------------------------------------------------- /* ---------------------------------------------------------------------
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <string.h> #include <string.h>
#include <arch.h> #include <arch.h>
#include <arch_features.h>
#include <arch_helpers.h> #include <arch_helpers.h>
#include <bl31/bl31.h> #include <bl31/bl31.h>
#include <bl31/ehf.h> #include <bl31/ehf.h>
...@@ -72,16 +73,16 @@ void bl31_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, ...@@ -72,16 +73,16 @@ void bl31_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2,
/* Perform early platform-specific setup */ /* Perform early platform-specific setup */
bl31_early_platform_setup2(arg0, arg1, arg2, arg3); bl31_early_platform_setup2(arg0, arg1, arg2, arg3);
/*
* Update pointer authentication key before the MMU is enabled. It is
* saved in the rodata section, that can be writen before enabling the
* MMU. This function must be called after the console is initialized
* in the early platform setup.
*/
bl_handle_pauth();
/* Perform late platform-specific setup */ /* Perform late platform-specific setup */
bl31_plat_arch_setup(); bl31_plat_arch_setup();
#if CTX_INCLUDE_PAUTH_REGS
/*
* Assert that the ARMv8.3-PAuth registers are present or an access
* fault will be triggered when they are being saved or restored.
*/
assert(is_armv8_3_pauth_present());
#endif /* CTX_INCLUDE_PAUTH_REGS */
} }
/******************************************************************************* /*******************************************************************************
......
...@@ -129,22 +129,13 @@ func tsp_entrypoint _align=3 ...@@ -129,22 +129,13 @@ func tsp_entrypoint _align=3
*/ */
bl tsp_setup bl tsp_setup
/* ---------------------------------------------
* Enable pointer authentication
* ---------------------------------------------
*/
#if ENABLE_PAUTH #if ENABLE_PAUTH
mrs x0, sctlr_el1
orr x0, x0, #SCTLR_EnIA_BIT
#if ENABLE_BTI
/* --------------------------------------------- /* ---------------------------------------------
* Enable PAC branch type compatibility * Program APIAKey_EL1
* and enable pointer authentication
* --------------------------------------------- * ---------------------------------------------
*/ */
bic x0, x0, #(SCTLR_BT0_BIT | SCTLR_BT1_BIT) bl pauth_init_enable_el1
#endif /* ENABLE_BTI */
msr sctlr_el1, x0
isb
#endif /* ENABLE_PAUTH */ #endif /* ENABLE_PAUTH */
/* --------------------------------------------- /* ---------------------------------------------
...@@ -271,6 +262,15 @@ func tsp_cpu_on_entry ...@@ -271,6 +262,15 @@ func tsp_cpu_on_entry
mov x0, #0 mov x0, #0
bl bl32_plat_enable_mmu bl bl32_plat_enable_mmu
#if ENABLE_PAUTH
/* ---------------------------------------------
* Program APIAKey_EL1
* and enable pointer authentication
* ---------------------------------------------
*/
bl pauth_init_enable_el1
#endif /* ENABLE_PAUTH */
/* --------------------------------------------- /* ---------------------------------------------
* Enter C runtime to perform any remaining * Enter C runtime to perform any remaining
* book keeping * book keeping
......
...@@ -4,14 +4,16 @@ ...@@ -4,14 +4,16 @@
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
#include <platform_def.h> #include <assert.h>
#include <arch_features.h>
#include <arch_helpers.h> #include <arch_helpers.h>
#include <bl32/tsp/tsp.h> #include <bl32/tsp/tsp.h>
#include <common/bl_common.h> #include <common/bl_common.h>
#include <common/debug.h> #include <common/debug.h>
#include <lib/spinlock.h> #include <lib/spinlock.h>
#include <plat/common/platform.h> #include <plat/common/platform.h>
#include <platform_def.h>
#include <platform_tsp.h> #include <platform_tsp.h>
#include "tsp_private.h" #include "tsp_private.h"
...@@ -79,16 +81,16 @@ void tsp_setup(void) ...@@ -79,16 +81,16 @@ void tsp_setup(void)
/* Perform early platform-specific setup */ /* Perform early platform-specific setup */
tsp_early_platform_setup(); tsp_early_platform_setup();
/*
* Update pointer authentication key before the MMU is enabled. It is
* saved in the rodata section, that can be writen before enabling the
* MMU. This function must be called after the console is initialized
* in the early platform setup.
*/
bl_handle_pauth();
/* Perform late platform-specific setup */ /* Perform late platform-specific setup */
tsp_plat_arch_setup(); tsp_plat_arch_setup();
#if ENABLE_PAUTH
/*
* Assert that the ARMv8.3-PAuth registers are present or an access
* fault will be triggered when they are being saved or restored.
*/
assert(is_armv8_3_pauth_present());
#endif /* ENABLE_PAUTH */
} }
/******************************************************************************* /*******************************************************************************
......
...@@ -244,53 +244,3 @@ void print_entry_point_info(const entry_point_info_t *ep_info) ...@@ -244,53 +244,3 @@ void print_entry_point_info(const entry_point_info_t *ep_info)
#endif #endif
#undef PRINT_IMAGE_ARG #undef PRINT_IMAGE_ARG
} }
#ifdef __aarch64__
/*******************************************************************************
* Handle all possible cases regarding ARMv8.3-PAuth.
******************************************************************************/
void bl_handle_pauth(void)
{
#if ENABLE_PAUTH
/*
* ENABLE_PAUTH = 1 && CTX_INCLUDE_PAUTH_REGS = 1
*
* Check that the system supports address authentication to avoid
* getting an access fault when accessing the registers. This is all
* that is needed to check. If any of the authentication mechanisms is
* supported, the system knows about ARMv8.3-PAuth, so all the registers
* are available and accessing them won't generate a fault.
*
* Obtain 128-bit instruction key A from the platform and save it to the
* system registers. Pointer authentication can't be enabled here or the
* authentication will fail when returning from this function.
*/
assert(is_armv8_3_pauth_apa_api_present());
uint64_t *apiakey = plat_init_apiakey();
write_apiakeylo_el1(apiakey[0]);
write_apiakeyhi_el1(apiakey[1]);
#else /* if !ENABLE_PAUTH */
# if CTX_INCLUDE_PAUTH_REGS
/*
* ENABLE_PAUTH = 0 && CTX_INCLUDE_PAUTH_REGS = 1
*
* Assert that the ARMv8.3-PAuth registers are present or an access
* fault will be triggered when they are being saved or restored.
*/
assert(is_armv8_3_pauth_present());
# else
/*
* ENABLE_PAUTH = 0 && CTX_INCLUDE_PAUTH_REGS = 0
*
* Pointer authentication is allowed in the Non-secure world, but
* prohibited in the Secure world. The Trusted Firmware doesn't save the
* registers during a world switch. No check needed.
*/
# endif /* CTX_INCLUDE_PAUTH_REGS */
#endif /* ENABLE_PAUTH */
}
#endif /* __aarch64__ */
...@@ -1796,21 +1796,21 @@ defined by the translation library, and can be found in the file ...@@ -1796,21 +1796,21 @@ defined by the translation library, and can be found in the file
On DynamIQ systems, this function must not use stack while enabling MMU, which On DynamIQ systems, this function must not use stack while enabling MMU, which
is how the function in xlat table library version 2 is implemented. is how the function in xlat table library version 2 is implemented.
Function : plat_init_apiakey [optional] Function : plat_init_apkey [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:: ::
Argument : void Argument : void
Return : uint64_t * Return : uint128_t
This function populates the ``plat_apiakey`` array that contains the values used This function returns the 128-bit value which can be used to program ARMv8.3
to set the ``APIAKey{Hi,Lo}_EL1`` registers. It returns a pointer to this array. pointer authentication keys.
The value should be obtained from a reliable source of randomness. The value should be obtained from a reliable source of randomness.
This function is only needed if ARMv8.3 pointer authentication is used in the This function is only needed if ARMv8.3 pointer authentication is used in the
Trusted Firmware by building with ``ENABLE_PAUTH=1``. Trusted Firmware by building with ``BRANCH_PROTECTION`` option set to non-zero.
Function : plat_get_syscnt_freq2() [mandatory] Function : plat_get_syscnt_freq2() [mandatory]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
......
...@@ -318,8 +318,9 @@ Common build options ...@@ -318,8 +318,9 @@ Common build options
- ``BRANCH_PROTECTION``: Numeric value to enable ARMv8.3 Pointer Authentication - ``BRANCH_PROTECTION``: Numeric value to enable ARMv8.3 Pointer Authentication
and ARMv8.5 Branch Target Identification support for TF-A BL images themselves. and ARMv8.5 Branch Target Identification support for TF-A BL images themselves.
If enabled, it is needed to use a compiler that supports the option If enabled, it is needed to use a compiler (e.g GCC 9.1 and later versions) that
``-mbranch-protection``. Selects the branch protection features to use: supports the option ``-mbranch-protection``.
Selects the branch protection features to use:
- 0: Default value turns off all types of branch protection - 0: Default value turns off all types of branch protection
- 1: Enables all types of branch protection features - 1: Enables all types of branch protection features
- 2: Return address signing to its standard level - 2: Return address signing to its standard level
...@@ -820,7 +821,6 @@ Common build options ...@@ -820,7 +821,6 @@ Common build options
cluster platforms). If this option is enabled, then warm boot path cluster platforms). If this option is enabled, then warm boot path
enables D-caches immediately after enabling MMU. This option defaults to 0. enables D-caches immediately after enabling MMU. This option defaults to 0.
Arm development platform specific build options Arm development platform specific build options
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......
...@@ -34,14 +34,6 @@ static inline bool is_armv8_3_pauth_present(void) ...@@ -34,14 +34,6 @@ static inline bool is_armv8_3_pauth_present(void)
return (read_id_aa64isar1_el1() & mask) != 0U; return (read_id_aa64isar1_el1() & mask) != 0U;
} }
static inline bool is_armv8_3_pauth_apa_api_present(void)
{
uint64_t mask = (ID_AA64ISAR1_API_MASK << ID_AA64ISAR1_API_SHIFT) |
(ID_AA64ISAR1_APA_MASK << ID_AA64ISAR1_APA_SHIFT);
return (read_id_aa64isar1_el1() & mask) != 0U;
}
static inline bool is_armv8_4_ttst_present(void) static inline bool is_armv8_4_ttst_present(void)
{ {
return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_ST_SHIFT) & return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_ST_SHIFT) &
......
...@@ -212,8 +212,7 @@ ...@@ -212,8 +212,7 @@
#define CTX_PACDBKEY_HI U(0x38) #define CTX_PACDBKEY_HI U(0x38)
#define CTX_PACGAKEY_LO U(0x40) #define CTX_PACGAKEY_LO U(0x40)
#define CTX_PACGAKEY_HI U(0x48) #define CTX_PACGAKEY_HI U(0x48)
#define CTX_PACGAKEY_END U(0x50) #define CTX_PAUTH_REGS_END U(0x50) /* Align to the next 16 byte boundary */
#define CTX_PAUTH_REGS_END U(0x60) /* Align to the next 16 byte boundary */
#else #else
#define CTX_PAUTH_REGS_END U(0) #define CTX_PAUTH_REGS_END U(0)
#endif /* CTX_INCLUDE_PAUTH_REGS */ #endif /* CTX_INCLUDE_PAUTH_REGS */
......
/* /*
* Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -11,21 +11,35 @@ ...@@ -11,21 +11,35 @@
#include <bl31/ehf.h> #include <bl31/ehf.h>
/* Size of psci_cpu_data structure */
#define PSCI_CPU_DATA_SIZE 12
#ifdef __aarch64__ #ifdef __aarch64__
/* Offsets for the cpu_data structure */ /* 8-bytes aligned size of psci_cpu_data structure */
#define CPU_DATA_CRASH_BUF_OFFSET 0x18 #define PSCI_CPU_DATA_SIZE_ALIGNED ((PSCI_CPU_DATA_SIZE + 7) & ~7)
/* Offset of cpu_ops_ptr, size 8 bytes */
#define CPU_DATA_CPU_OPS_PTR 0x10
#if ENABLE_PAUTH
/* 8-bytes aligned offset of apiakey[2], size 16 bytes */
#define CPU_DATA_APIAKEY_OFFSET (0x18 + PSCI_CPU_DATA_SIZE_ALIGNED)
#define CPU_DATA_CRASH_BUF_OFFSET (CPU_DATA_APIAKEY_OFFSET + 0x10)
#else
#define CPU_DATA_CRASH_BUF_OFFSET (0x18 + PSCI_CPU_DATA_SIZE_ALIGNED)
#endif /* ENABLE_PAUTH */
/* need enough space in crash buffer to save 8 registers */ /* need enough space in crash buffer to save 8 registers */
#define CPU_DATA_CRASH_BUF_SIZE 64 #define CPU_DATA_CRASH_BUF_SIZE 64
#define CPU_DATA_CPU_OPS_PTR 0x10
#else /* __aarch64__ */ #else /* !__aarch64__ */
#if CRASH_REPORTING #if CRASH_REPORTING
#error "Crash reporting is not supported in AArch32" #error "Crash reporting is not supported in AArch32"
#endif #endif
#define CPU_DATA_CPU_OPS_PTR 0x0 #define CPU_DATA_CPU_OPS_PTR 0x0
#define CPU_DATA_CRASH_BUF_OFFSET 0x4 #define CPU_DATA_CRASH_BUF_OFFSET (0x4 + PSCI_CPU_DATA_SIZE)
#endif /* __aarch64__ */ #endif /* __aarch64__ */
...@@ -88,13 +102,16 @@ typedef struct cpu_data { ...@@ -88,13 +102,16 @@ typedef struct cpu_data {
void *cpu_context[2]; void *cpu_context[2];
#endif #endif
uintptr_t cpu_ops_ptr; uintptr_t cpu_ops_ptr;
struct psci_cpu_data psci_svc_cpu_data;
#if ENABLE_PAUTH
uint64_t apiakey[2];
#endif
#if CRASH_REPORTING #if CRASH_REPORTING
u_register_t crash_buf[CPU_DATA_CRASH_BUF_SIZE >> 3]; u_register_t crash_buf[CPU_DATA_CRASH_BUF_SIZE >> 3];
#endif #endif
#if ENABLE_RUNTIME_INSTRUMENTATION #if ENABLE_RUNTIME_INSTRUMENTATION
uint64_t cpu_data_pmf_ts[CPU_DATA_PMF_TS_COUNT]; uint64_t cpu_data_pmf_ts[CPU_DATA_PMF_TS_COUNT];
#endif #endif
struct psci_cpu_data psci_svc_cpu_data;
#if PLAT_PCPU_DATA_SIZE #if PLAT_PCPU_DATA_SIZE
uint8_t platform_cpu_data[PLAT_PCPU_DATA_SIZE]; uint8_t platform_cpu_data[PLAT_PCPU_DATA_SIZE];
#endif #endif
...@@ -105,6 +122,12 @@ typedef struct cpu_data { ...@@ -105,6 +122,12 @@ typedef struct cpu_data {
extern cpu_data_t percpu_data[PLATFORM_CORE_COUNT]; extern cpu_data_t percpu_data[PLATFORM_CORE_COUNT];
#if ENABLE_PAUTH
CASSERT(CPU_DATA_APIAKEY_OFFSET == __builtin_offsetof
(cpu_data_t, apiakey),
assert_cpu_data_crash_stack_offset_mismatch);
#endif
#if CRASH_REPORTING #if CRASH_REPORTING
/* verify assembler offsets match data structures */ /* verify assembler offsets match data structures */
CASSERT(CPU_DATA_CRASH_BUF_OFFSET == __builtin_offsetof CASSERT(CPU_DATA_CRASH_BUF_OFFSET == __builtin_offsetof
......
/*
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef PAUTH_H
#define PAUTH_H
/*******************************************************************************
* ARMv8.3-PAuth support functions
******************************************************************************/
/* Disable ARMv8.3 pointer authentication in EL1/EL3 */
void pauth_disable_el1(void);
void pauth_disable_el3(void);
#endif /* PAUTH_H */
...@@ -104,7 +104,6 @@ void plat_panic_handler(void) __dead2; ...@@ -104,7 +104,6 @@ void plat_panic_handler(void) __dead2;
const char *plat_log_get_prefix(unsigned int log_level); const char *plat_log_get_prefix(unsigned int log_level);
void bl2_plat_preload_setup(void); void bl2_plat_preload_setup(void);
int plat_try_next_boot_source(void); int plat_try_next_boot_source(void);
uint64_t *plat_init_apiakey(void);
/******************************************************************************* /*******************************************************************************
* Mandatory BL1 functions * Mandatory BL1 functions
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment