mirror of https://gitee.com/openkylin/qemu.git
target/arm: Rebuild hflags at MSR writes
Continue setting, but not relying upon, env->hflags. Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20191023150057.25731-18-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
a8a79c7a07
commit
69d66864f7
|
@ -1789,8 +1789,17 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
|
||||||
if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
|
if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
|
||||||
/* I/O operations must end the TB here (whether read or write) */
|
/* I/O operations must end the TB here (whether read or write) */
|
||||||
s->base.is_jmp = DISAS_UPDATE;
|
s->base.is_jmp = DISAS_UPDATE;
|
||||||
} else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
|
}
|
||||||
/* We default to ending the TB on a coprocessor register write,
|
if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
|
||||||
|
/*
|
||||||
|
* A write to any coprocessor regiser that ends a TB
|
||||||
|
* must rebuild the hflags for the next TB.
|
||||||
|
*/
|
||||||
|
TCGv_i32 tcg_el = tcg_const_i32(s->current_el);
|
||||||
|
gen_helper_rebuild_hflags_a64(cpu_env, tcg_el);
|
||||||
|
tcg_temp_free_i32(tcg_el);
|
||||||
|
/*
|
||||||
|
* We default to ending the TB on a coprocessor register write,
|
||||||
* but allow this to be suppressed by the register definition
|
* but allow this to be suppressed by the register definition
|
||||||
* (usually only necessary to work around guest bugs).
|
* (usually only necessary to work around guest bugs).
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -6890,6 +6890,8 @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
|
||||||
ri = get_arm_cp_reginfo(s->cp_regs,
|
ri = get_arm_cp_reginfo(s->cp_regs,
|
||||||
ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
|
ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
|
||||||
if (ri) {
|
if (ri) {
|
||||||
|
bool need_exit_tb;
|
||||||
|
|
||||||
/* Check access permissions */
|
/* Check access permissions */
|
||||||
if (!cp_access_ok(s->current_el, ri, isread)) {
|
if (!cp_access_ok(s->current_el, ri, isread)) {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -7068,14 +7070,30 @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
|
|
||||||
/* I/O operations must end the TB here (whether read or write) */
|
/* I/O operations must end the TB here (whether read or write) */
|
||||||
gen_lookup_tb(s);
|
need_exit_tb = ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) &&
|
||||||
} else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
|
(ri->type & ARM_CP_IO));
|
||||||
/* We default to ending the TB on a coprocessor register write,
|
|
||||||
|
if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
|
||||||
|
/*
|
||||||
|
* A write to any coprocessor regiser that ends a TB
|
||||||
|
* must rebuild the hflags for the next TB.
|
||||||
|
*/
|
||||||
|
TCGv_i32 tcg_el = tcg_const_i32(s->current_el);
|
||||||
|
if (arm_dc_feature(s, ARM_FEATURE_M)) {
|
||||||
|
gen_helper_rebuild_hflags_m32(cpu_env, tcg_el);
|
||||||
|
} else {
|
||||||
|
gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
|
||||||
|
}
|
||||||
|
tcg_temp_free_i32(tcg_el);
|
||||||
|
/*
|
||||||
|
* We default to ending the TB on a coprocessor register write,
|
||||||
* but allow this to be suppressed by the register definition
|
* but allow this to be suppressed by the register definition
|
||||||
* (usually only necessary to work around guest bugs).
|
* (usually only necessary to work around guest bugs).
|
||||||
*/
|
*/
|
||||||
|
need_exit_tb = true;
|
||||||
|
}
|
||||||
|
if (need_exit_tb) {
|
||||||
gen_lookup_tb(s);
|
gen_lookup_tb(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue