diff --git a/common/feat_detect.c b/common/feat_detect.c index a885107b8..abb6d718c 100644 --- a/common/feat_detect.c +++ b/common/feat_detect.c @@ -90,16 +90,6 @@ static void read_feat_pan(void) #endif } -/****************************************************** - * Feature : FEAT_VHE (Virtualization Host Extensions) - *****************************************************/ -static void read_feat_vhe(void) -{ -#if (ENABLE_FEAT_VHE == FEAT_STATE_ALWAYS) - feat_detect_panic(is_armv8_1_vhe_present(), "VHE"); -#endif -} - /******************************************************************************* * Feature : FEAT_RAS (Reliability, Availability, and Serviceability Extension) ******************************************************************************/ @@ -271,7 +261,7 @@ void detect_arch_features(void) /* v8.1 features */ read_feat_pan(); - read_feat_vhe(); + check_feature(ENABLE_FEAT_VHE, read_feat_vhe_id_field(), "VHE", 1, 1); /* v8.2 features */ read_feat_ras(); diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index cafc1e8bc..85546ec47 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -121,6 +121,8 @@ #define TRFCR_EL2 S3_4_C1_C2_1 #define PMSCR_EL2 S3_4_C9_C9_0 #define TFSR_EL2 S3_4_C5_C6_0 +#define CONTEXTIDR_EL2 S3_4_C13_C0_1 +#define TTBR1_EL2 S3_4_C2_C0_1 /******************************************************************************* * Generic timer memory mapped registers & offsets diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h index 1bb6a8c2a..f1a13d290 100644 --- a/include/arch/aarch64/arch_features.h +++ b/include/arch/aarch64/arch_features.h @@ -27,10 +27,22 @@ static inline bool is_armv8_1_pan_present(void) ID_AA64MMFR1_EL1_PAN_MASK) != 0U; } -static inline bool is_armv8_1_vhe_present(void) +static inline unsigned int read_feat_vhe_id_field(void) { - return ((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_VHE_SHIFT) & - ID_AA64MMFR1_EL1_VHE_MASK) != 0U; + return ISOLATE_FIELD(read_id_aa64mmfr1_el1(), ID_AA64MMFR1_EL1_VHE); +} + +static inline bool is_feat_vhe_supported(void) +{ + if (ENABLE_FEAT_VHE == FEAT_STATE_DISABLED) { + return false; + } + + if (ENABLE_FEAT_VHE == FEAT_STATE_ALWAYS) { + return true; + } + + return read_feat_vhe_id_field() != 0U; } static inline bool is_armv8_2_ttcnp_present(void) diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index e45fb8944..6d115c7e5 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -540,6 +540,10 @@ DEFINE_RENAME_SYSREG_READ_FUNC(erxaddr_el1, ERXADDR_EL1) DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc0_el1, ERXMISC0_EL1) DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc1_el1, ERXMISC1_EL1) +/* Armv8.1 VHE Registers */ +DEFINE_RENAME_SYSREG_RW_FUNCS(contextidr_el2, CONTEXTIDR_EL2) +DEFINE_RENAME_SYSREG_RW_FUNCS(ttbr1_el2, TTBR1_EL2) + /* Armv8.2 ID Registers */ DEFINE_RENAME_IDREG_READ_FUNC(id_aa64mmfr2_el1, ID_AA64MMFR2_EL1) diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h index 838e74484..9b50f3319 100644 --- a/include/lib/el3_runtime/aarch64/context.h +++ b/include/lib/el3_runtime/aarch64/context.h @@ -521,10 +521,6 @@ void el2_sysregs_context_restore_mte(el2_sysregs_t *regs); void el2_sysregs_context_save_ecv(el2_sysregs_t *regs); void el2_sysregs_context_restore_ecv(el2_sysregs_t *regs); #endif /* ENABLE_FEAT_ECV */ -#if ENABLE_FEAT_VHE -void el2_sysregs_context_save_vhe(el2_sysregs_t *regs); -void el2_sysregs_context_restore_vhe(el2_sysregs_t *regs); -#endif /* ENABLE_FEAT_VHE */ #if RAS_EXTENSION void el2_sysregs_context_save_ras(el2_sysregs_t *regs); void el2_sysregs_context_restore_ras(el2_sysregs_t *regs); diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S index 7bb0f99a6..a5b64a5f2 100644 --- a/lib/el3_runtime/aarch64/context.S +++ b/lib/el3_runtime/aarch64/context.S @@ -21,10 +21,6 @@ .global el2_sysregs_context_save_ecv .global el2_sysregs_context_restore_ecv #endif /* ENABLE_FEAT_ECV */ -#if ENABLE_FEAT_VHE - .global el2_sysregs_context_save_vhe - .global el2_sysregs_context_restore_vhe -#endif /* ENABLE_FEAT_VHE */ #if RAS_EXTENSION .global el2_sysregs_context_save_ras .global el2_sysregs_context_restore_ras @@ -240,30 +236,6 @@ func el2_sysregs_context_restore_ecv endfunc el2_sysregs_context_restore_ecv #endif /* ENABLE_FEAT_ECV */ -#if ENABLE_FEAT_VHE -func el2_sysregs_context_save_vhe - /* - * CONTEXTIDR_EL2 register is saved only when FEAT_VHE or - * FEAT_Debugv8p2 (currently not in TF-A) is supported. - */ - mrs x9, contextidr_el2 - mrs x10, ttbr1_el2 - stp x9, x10, [x0, #CTX_CONTEXTIDR_EL2] - ret -endfunc el2_sysregs_context_save_vhe - -func el2_sysregs_context_restore_vhe - /* - * CONTEXTIDR_EL2 register is restored only when FEAT_VHE or - * FEAT_Debugv8p2 (currently not in TF-A) is supported. - */ - ldp x9, x10, [x0, #CTX_CONTEXTIDR_EL2] - msr contextidr_el2, x9 - msr ttbr1_el2, x10 - ret -endfunc el2_sysregs_context_restore_vhe -#endif /* ENABLE_FEAT_VHE */ - #if RAS_EXTENSION func el2_sysregs_context_save_ras /* diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index eb5d1dbf2..20eb5f67d 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -960,9 +960,12 @@ void cm_el2_sysregs_context_save(uint32_t security_state) #if ENABLE_FEAT_ECV el2_sysregs_context_save_ecv(el2_sysregs_ctx); #endif -#if ENABLE_FEAT_VHE - el2_sysregs_context_save_vhe(el2_sysregs_ctx); -#endif + if (is_feat_vhe_supported()) { + write_ctx_reg(el2_sysregs_ctx, CTX_CONTEXTIDR_EL2, + read_contextidr_el2()); + write_ctx_reg(el2_sysregs_ctx, CTX_TTBR1_EL2, + read_ttbr1_el2()); + } #if RAS_EXTENSION el2_sysregs_context_save_ras(el2_sysregs_ctx); #endif @@ -1020,9 +1023,10 @@ void cm_el2_sysregs_context_restore(uint32_t security_state) #if ENABLE_FEAT_ECV el2_sysregs_context_restore_ecv(el2_sysregs_ctx); #endif -#if ENABLE_FEAT_VHE - el2_sysregs_context_restore_vhe(el2_sysregs_ctx); -#endif + if (is_feat_vhe_supported()) { + write_contextidr_el2(read_ctx_reg(el2_sysregs_ctx, CTX_CONTEXTIDR_EL2)); + write_ttbr1_el2(read_ctx_reg(el2_sysregs_ctx, CTX_TTBR1_EL2)); + } #if RAS_EXTENSION el2_sysregs_context_restore_ras(el2_sysregs_ctx); #endif diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 2e7ff480b..435a35e3d 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -469,6 +469,7 @@ ENABLE_FEAT_FGT := 2 ENABLE_FEAT_HCX := 2 ENABLE_FEAT_TCR2 := 2 +ENABLE_FEAT_VHE := 2 ENABLE_MPAM_FOR_LOWER_ELS := 2 ifeq (${SPMC_AT_EL3}, 1) diff --git a/services/std_svc/sdei/sdei_intr_mgmt.c b/services/std_svc/sdei/sdei_intr_mgmt.c index 87a1fb7dc..9862e4f8d 100644 --- a/services/std_svc/sdei/sdei_intr_mgmt.c +++ b/services/std_svc/sdei/sdei_intr_mgmt.c @@ -270,7 +270,7 @@ static void sdei_set_elr_spsr(sdei_entry_t *se, sdei_dispatch_context_t *disp_ct * HCR_EL2.E2H = 1 and HCR_EL2.TGE = 1 */ u_register_t hcr_el2 = read_hcr(); - bool el_is_in_host = is_armv8_1_vhe_present() && + bool el_is_in_host = (read_feat_vhe_id_field() != 0U) && (hcr_el2 & HCR_TGE_BIT) && (hcr_el2 & HCR_E2H_BIT);