It is incorrect to call arm_el_is_aa64() function for unimplemented EL. This patch fixes several attempts to do so.
Signed-off-by: Sergey Sorokin <afaral...@yandex.ru> --- target-arm/cpu.h | 8 +++++--- target-arm/helper.c | 15 +++++++++++++-- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/target-arm/cpu.h b/target-arm/cpu.h index cc1578c..df456a5 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -1015,11 +1015,11 @@ static inline bool access_secure_reg(CPUARMState *env) */ #define A32_BANKED_CURRENT_REG_GET(_env, _regname) \ A32_BANKED_REG_GET((_env), _regname, \ - ((!arm_el_is_aa64((_env), 3) && arm_is_secure(_env)))) + (arm_is_secure(_env) && !arm_el_is_aa64((_env), 3))) #define A32_BANKED_CURRENT_REG_SET(_env, _regname, _val) \ A32_BANKED_REG_SET((_env), _regname, \ - ((!arm_el_is_aa64((_env), 3) && arm_is_secure(_env))), \ + (arm_is_secure(_env) && !arm_el_is_aa64((_env), 3)), \ (_val)) void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf); @@ -1586,7 +1586,9 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx, * interrupt. */ if ((target_el > cur_el) && (target_el != 1)) { - if (arm_el_is_aa64(env, 3) || ((scr || hcr) && (!secure))) { + /* ARM_FEATURE_AARCH64 enabled means the higher EL is AArch64. */ + if (arm_feature(env, ARM_FEATURE_AARCH64) || + ((scr || hcr) && (!secure))) { unmasked = 1; } } diff --git a/target-arm/helper.c b/target-arm/helper.c index 8367997..1f11dbd 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -5220,11 +5220,22 @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx, uint32_t cur_el, bool secure) { CPUARMState *env = cs->env_ptr; - int rw = ((env->cp15.scr_el3 & SCR_RW) == SCR_RW); + int rw; int scr; int hcr; int target_el; - int is64 = arm_el_is_aa64(env, 3); + /* Is the higher EL AArch64? */ + int is64 = arm_feature(env, ARM_FEATURE_AARCH64); + + /* If the highest EL is in AArch64 state, and EL3 is not implemented, + * we must behave as if EL3 is implemented and is in AArch64 state. + * Therefore we need appropriate RW bit. + */ + if (arm_feature(env, ARM_FEATURE_EL3)) { + rw = ((env->cp15.scr_el3 & SCR_RW) == SCR_RW); + } else { + rw = is64; + } switch (excp_idx) { case EXCP_IRQ: -- 1.9.3