From e6d32dc2e01dceedc26acfe2181ddf6aeeb43b3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= Date: Thu, 4 Mar 2021 15:03:05 -0500 Subject: [PATCH] target/arm: Implement SCR_EL2.EEL2 This adds handling for the SCR_EL3.EEL2 bit. Backports 926c1b97895879b78ca14bca2831c08740ed1c38 --- qemu/target/arm/cpu.c | 2 +- qemu/target/arm/cpu.h | 8 ++++++-- qemu/target/arm/helper.c | 19 ++++++++++++++++--- qemu/target/arm/translate.c | 16 ++++++++++++++-- 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/qemu/target/arm/cpu.c b/qemu/target/arm/cpu.c index 67965755..cc7457c6 100644 --- a/qemu/target/arm/cpu.c +++ b/qemu/target/arm/cpu.c @@ -473,7 +473,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx, * masked from Secure state. The HCR and SCR settings * don't affect the masking logic, only the interrupt routing. */ - if (target_el == 3 || !secure) { + if (target_el == 3 || !secure || (env->cp15.scr_el3 & SCR_EEL2)) { unmasked = true; } } else { diff --git a/qemu/target/arm/cpu.h b/qemu/target/arm/cpu.h index 4935b099..8d1969ac 100644 --- a/qemu/target/arm/cpu.h +++ b/qemu/target/arm/cpu.h @@ -2032,7 +2032,10 @@ static inline bool arm_is_secure(CPUARMState *env) static inline bool arm_is_el2_enabled(CPUARMState *env) { if (arm_feature(env, ARM_FEATURE_EL2)) { - return !arm_is_secure_below_el3(env); + if (arm_is_secure_below_el3(env)) { + return (env->cp15.scr_el3 & SCR_EEL2) != 0; + } + return true; } return false; } @@ -2079,7 +2082,8 @@ static inline bool arm_el_is_aa64(CPUARMState *env, int el) return aa64; } - if (arm_feature(env, ARM_FEATURE_EL3)) { + if (arm_feature(env, ARM_FEATURE_EL3) && + ((env->cp15.scr_el3 & SCR_NS) || !(env->cp15.scr_el3 & SCR_EEL2))) { aa64 = aa64 && (env->cp15.scr_el3 & SCR_RW); } diff --git a/qemu/target/arm/helper.c b/qemu/target/arm/helper.c index eee3f257..f108c06a 100644 --- a/qemu/target/arm/helper.c +++ b/qemu/target/arm/helper.c @@ -272,6 +272,9 @@ static CPAccessResult access_trap_aa32s_el1(CPUARMState *env, return CP_ACCESS_OK; } if (arm_is_secure_below_el3(env)) { + if (env->cp15.scr_el3 & SCR_EEL2) { + return CP_ACCESS_TRAP_EL2; + } return CP_ACCESS_TRAP_EL3; } /* This will be EL1 NS and EL2 NS, which just UNDEF */ @@ -1723,6 +1726,9 @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) if (cpu_isar_feature(aa64_pauth, cpu)) { valid_mask |= SCR_API | SCR_APK; } + if (cpu_isar_feature(aa64_sel2, cpu)) { + valid_mask |= SCR_EEL2; + } if (cpu_isar_feature(aa64_mte, cpu)) { valid_mask |= SCR_ATA; } @@ -3080,13 +3086,16 @@ static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri, bool isread) { if (ri->opc2 & 4) { - /* The ATS12NSO* operations must trap to EL3 if executed in + /* The ATS12NSO* operations must trap to EL3 or EL2 if executed in * Secure EL1 (which can only happen if EL3 is AArch64). * They are simply UNDEF if executed from NS EL1. * They function normally from EL2 or EL3. */ if (arm_current_el(env) == 1) { if (arm_is_secure_below_el3(env)) { + if (env->cp15.scr_el3 & SCR_EEL2) { + return CP_ACCESS_TRAP_UNCATEGORIZED_EL2; + } return CP_ACCESS_TRAP_UNCATEGORIZED_EL3; } return CP_ACCESS_TRAP_UNCATEGORIZED; @@ -3349,7 +3358,8 @@ static void ats1h_write(CPUARMState *env, const ARMCPRegInfo *ri, static CPAccessResult at_s1e2_access(CPUARMState *env, const ARMCPRegInfo *ri, bool isread) { - if (arm_current_el(env) == 3 && !(env->cp15.scr_el3 & SCR_NS)) { + if (arm_current_el(env) == 3 && + !(env->cp15.scr_el3 & (SCR_NS | SCR_EEL2))) { return CP_ACCESS_TRAP; } return CP_ACCESS_OK; @@ -5430,12 +5440,15 @@ static CPAccessResult nsacr_access(CPUARMState *env, const ARMCPRegInfo *ri, bool isread) { /* The NSACR is RW at EL3, and RO for NS EL1 and NS EL2. - * At Secure EL1 it traps to EL3. + * At Secure EL1 it traps to EL3 or EL2. */ if (arm_current_el(env) == 3) { return CP_ACCESS_OK; } if (arm_is_secure_below_el3(env)) { + if (env->cp15.scr_el3 & SCR_EEL2) { + return CP_ACCESS_TRAP_EL2; + } return CP_ACCESS_TRAP_EL3; } /* Accesses from EL1 NS and EL2 NS are UNDEF for write but allow reads. */ diff --git a/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index 92f54e5c..4897e57b 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -2796,6 +2796,7 @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn, int *tgtmode, int *regno) { TCGContext *tcg_ctx = s->uc->tcg_ctx; + /* Decode the r and sysm fields of MSR/MRS banked accesses into * the target mode and register number, and identify the various * unpredictable cases. @@ -2930,9 +2931,20 @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn, } if (s->current_el == 1) { /* If we're in Secure EL1 (which implies that EL3 is AArch64) - * then accesses to Mon registers trap to EL3 + * then accesses to Mon registers trap to Secure EL2, if it exists, + * otherwise EL3. */ - TCGv_i32 tcg_el = tcg_const_i32(tcg_ctx, 3); + TCGv_i32 tcg_el; + + if (arm_dc_feature(s, ARM_FEATURE_AARCH64) && + dc_isar_feature(aa64_sel2, s)) { + /* Target EL is EL<3 minus SCR_EL3.EEL2> */ + tcg_el = load_cpu_field(s, cp15.scr_el3); + tcg_gen_sextract_i32(tcg_ctx, tcg_el, tcg_el, ctz32(SCR_EEL2), 1); + tcg_gen_addi_i32(tcg_ctx, tcg_el, tcg_el, 3); + } else { + tcg_el = tcg_const_i32(tcg_ctx, 3); + } gen_exception_el(s, EXCP_UDEF, syn_uncategorized(), tcg_el); tcg_temp_free_i32(tcg_ctx, tcg_el);