From ed108b56051de5da8024568a06781ce287e86c78 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Fri, 13 Sep 2019 14:11:59 +0100 Subject: 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: Alexei Fedorov --- include/arch/aarch64/arch_features.h | 8 ------- include/lib/el3_runtime/aarch64/context.h | 3 +-- include/lib/el3_runtime/cpu_data.h | 39 ++++++++++++++++++++++++------- include/lib/extensions/pauth.h | 18 ++++++++++++++ include/plat/common/platform.h | 1 - 5 files changed, 50 insertions(+), 19 deletions(-) create mode 100644 include/lib/extensions/pauth.h (limited to 'include') diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h index 2f29f487..0491f48c 100644 --- a/include/arch/aarch64/arch_features.h +++ b/include/arch/aarch64/arch_features.h @@ -34,14 +34,6 @@ static inline bool is_armv8_3_pauth_present(void) 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) { return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_ST_SHIFT) & diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h index e90a6e7d..7a1f3a3a 100644 --- a/include/lib/el3_runtime/aarch64/context.h +++ b/include/lib/el3_runtime/aarch64/context.h @@ -212,8 +212,7 @@ #define CTX_PACDBKEY_HI U(0x38) #define CTX_PACGAKEY_LO U(0x40) #define CTX_PACGAKEY_HI U(0x48) -#define CTX_PACGAKEY_END U(0x50) -#define CTX_PAUTH_REGS_END U(0x60) /* Align to the next 16 byte boundary */ +#define CTX_PAUTH_REGS_END U(0x50) /* Align to the next 16 byte boundary */ #else #define CTX_PAUTH_REGS_END U(0) #endif /* CTX_INCLUDE_PAUTH_REGS */ diff --git a/include/lib/el3_runtime/cpu_data.h b/include/lib/el3_runtime/cpu_data.h index 55db4cff..54261358 100644 --- a/include/lib/el3_runtime/cpu_data.h +++ b/include/lib/el3_runtime/cpu_data.h @@ -1,5 +1,5 @@ /* - * 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 */ @@ -11,23 +11,37 @@ #include +/* Size of psci_cpu_data structure */ +#define PSCI_CPU_DATA_SIZE 12 + #ifdef __aarch64__ -/* Offsets for the cpu_data structure */ -#define CPU_DATA_CRASH_BUF_OFFSET 0x18 +/* 8-bytes aligned size of psci_cpu_data structure */ +#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 */ #define CPU_DATA_CRASH_BUF_SIZE 64 -#define CPU_DATA_CPU_OPS_PTR 0x10 -#else /* __aarch64__ */ +#else /* !__aarch64__ */ #if CRASH_REPORTING #error "Crash reporting is not supported in AArch32" #endif #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__ */ #if CRASH_REPORTING #define CPU_DATA_CRASH_BUF_END (CPU_DATA_CRASH_BUF_OFFSET + \ @@ -88,13 +102,16 @@ typedef struct cpu_data { void *cpu_context[2]; #endif uintptr_t cpu_ops_ptr; + struct psci_cpu_data psci_svc_cpu_data; +#if ENABLE_PAUTH + uint64_t apiakey[2]; +#endif #if CRASH_REPORTING u_register_t crash_buf[CPU_DATA_CRASH_BUF_SIZE >> 3]; #endif #if ENABLE_RUNTIME_INSTRUMENTATION uint64_t cpu_data_pmf_ts[CPU_DATA_PMF_TS_COUNT]; #endif - struct psci_cpu_data psci_svc_cpu_data; #if PLAT_PCPU_DATA_SIZE uint8_t platform_cpu_data[PLAT_PCPU_DATA_SIZE]; #endif @@ -105,6 +122,12 @@ typedef struct cpu_data { 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 /* verify assembler offsets match data structures */ CASSERT(CPU_DATA_CRASH_BUF_OFFSET == __builtin_offsetof diff --git a/include/lib/extensions/pauth.h b/include/lib/extensions/pauth.h new file mode 100644 index 00000000..2e780dec --- /dev/null +++ b/include/lib/extensions/pauth.h @@ -0,0 +1,18 @@ +/* + * 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 */ diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 3f9ab1b6..eeae6214 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -104,7 +104,6 @@ void plat_panic_handler(void) __dead2; const char *plat_log_get_prefix(unsigned int log_level); void bl2_plat_preload_setup(void); int plat_try_next_boot_source(void); -uint64_t *plat_init_apiakey(void); /******************************************************************************* * Mandatory BL1 functions -- cgit v1.2.3