diff --git a/docs/firmware-design.rst b/docs/firmware-design.rst index 7cc7485..051b92b 100644 --- a/docs/firmware-design.rst +++ b/docs/firmware-design.rst @@ -2532,6 +2532,12 @@ translation table entries for a given stage of translation for a particular translation regime. +Armv8.3-A +~~~~~~~~~ + +- Pointer Authentication features of Armv8.3-A are unconditionally enabled so + that lower ELs are allowed to use them without causing a trap to EL3. + Armv7-A ~~~~~~~ diff --git a/include/common/aarch64/el3_common_macros.S b/include/common/aarch64/el3_common_macros.S index 03b977e..143c70c 100644 --- a/include/common/aarch64/el3_common_macros.S +++ b/include/common/aarch64/el3_common_macros.S @@ -70,9 +70,14 @@ * * SCR_EL3.EA: Set to one to route External Aborts and SError Interrupts * to EL3 when executing at any EL. + * + * SCR_EL3.{API,APK}: For Armv8.3 pointer authentication feature, + * disable traps to EL3 when accessing key registers or using pointer + * authentication instructions from lower ELs. * --------------------------------------------------------------------- */ - mov x0, #((SCR_RESET_VAL | SCR_EA_BIT | SCR_SIF_BIT) \ + mov_imm x0, ((SCR_RESET_VAL | SCR_EA_BIT | SCR_SIF_BIT | \ + SCR_API_BIT | SCR_APK_BIT) \ & ~(SCR_TWE_BIT | SCR_TWI_BIT | SCR_SMD_BIT)) msr scr_el3, x0 diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h index a6022cb..e6842e1 100644 --- a/include/lib/aarch64/arch.h +++ b/include/lib/aarch64/arch.h @@ -218,6 +218,8 @@ /* SCR definitions */ #define SCR_RES1_BITS ((U(1) << 4) | (U(1) << 5)) #define SCR_FIEN_BIT (U(1) << 21) +#define SCR_API_BIT (U(1) << 17) +#define SCR_APK_BIT (U(1) << 16) #define SCR_TWE_BIT (U(1) << 13) #define SCR_TWI_BIT (U(1) << 12) #define SCR_ST_BIT (U(1) << 11) @@ -274,6 +276,8 @@ #define VTTBR_BADDR_SHIFT U(0) /* HCR definitions */ +#define HCR_API_BIT (ULL(1) << 41) +#define HCR_APK_BIT (ULL(1) << 40) #define HCR_RW_SHIFT U(31) #define HCR_RW_BIT (ULL(1) << HCR_RW_SHIFT) #define HCR_AMO_BIT (ULL(1) << 5) diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index acc8d6d..d3984a2 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -290,6 +290,7 @@ uint32_t sctlr_elx, scr_el3, mdcr_el2; cpu_context_t *ctx = cm_get_context(security_state); int el2_unused = 0; + uint64_t hcr_el2 = 0; assert(ctx); @@ -309,13 +310,20 @@ * EL2 present but unused, need to disable safely. * SCTLR_EL2 can be ignored in this case. * - * Initialise all fields in HCR_EL2, except HCR_EL2.RW, - * to zero so that Non-secure operations do not trap to - * EL2. - * - * HCR_EL2.RW: Set this field to match SCR_EL3.RW + * Set EL2 register width appropriately: Set HCR_EL2 + * field to match SCR_EL3.RW. */ - write_hcr_el2((scr_el3 & SCR_RW_BIT) ? HCR_RW_BIT : 0); + if (scr_el3 & SCR_RW_BIT) + hcr_el2 |= HCR_RW_BIT; + + /* + * For Armv8.3 pointer authentication feature, disable + * traps to EL2 when accessing key registers or using + * pointer authentication instructions from lower ELs. + */ + hcr_el2 |= (HCR_API_BIT | HCR_APK_BIT); + + write_hcr_el2(hcr_el2); /* * Initialise CPTR_EL2 setting all fields rather than