diff --git a/qemu/target-arm/op_helper.c b/qemu/target-arm/op_helper.c index e8aed10a..025870d6 100644 --- a/qemu/target-arm/op_helper.c +++ b/qemu/target-arm/op_helper.c @@ -468,6 +468,14 @@ void HELPER(set_r13_banked)(CPUARMState *env, uint32_t mode, uint32_t val) uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode) { + if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_SYS) { + /* SRS instruction is UNPREDICTABLE from System mode; we UNDEF. + * Other UNPREDICTABLE and UNDEF cases were caught at translate time. + */ + raise_exception(env, EXCP_UDEF, syn_uncategorized(), + exception_target_el(env)); + } + if ((env->uncached_cpsr & CPSR_M) == mode) { return env->regs[13]; } else { diff --git a/qemu/target-arm/translate.c b/qemu/target-arm/translate.c index d3f603d9..a4253575 100644 --- a/qemu/target-arm/translate.c +++ b/qemu/target-arm/translate.c @@ -7720,10 +7720,7 @@ static void gen_srs(DisasContext *s, * -- not a valid mode number * -- a mode that's at a higher exception level * -- Monitor, if we are Non-secure - * For the UNPREDICTABLE cases we choose to UNDEF, except that for - * "current mode is System" we will write a garbage SPSR. - * (This is because we don't have access to our current mode here - * and would have to do a runtime check to UNDEF for System.) + * For the UNPREDICTABLE cases we choose to UNDEF. */ if (s->current_el == 1 && !s->ns) { gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3); @@ -7769,6 +7766,9 @@ static void gen_srs(DisasContext *s, addr = tcg_temp_new_i32(tcg_ctx); tmp = tcg_const_i32(tcg_ctx, mode); + /* get_r13_banked() will raise an exception if called from System mode */ + gen_set_condexec(s); + gen_set_pc_im(s, s->pc - 4); gen_helper_get_r13_banked(tcg_ctx, addr, tcg_ctx->cpu_env, tmp); tcg_temp_free_i32(tcg_ctx, tmp); switch (amode) { @@ -7818,6 +7818,7 @@ static void gen_srs(DisasContext *s, tcg_temp_free_i32(tcg_ctx, tmp); } tcg_temp_free_i32(tcg_ctx, addr); + s->is_jmp = DISAS_UPDATE; } static void disas_arm_insn(DisasContext *s, unsigned int insn) // qq