From: Dmitry Poletaev <dmitry.polet...@ispras.ru> Subject: [PATCH] target-i386: fix iret emulation correctness
Signed-off-by: Dmitry Poletaev <dmitry.polet...@ispras.ru> According to Intel manual: "If the NMI handler is a virtual-8086 task with an IOPL of less than 3, an IRET instruction issued from the handler generates a general-protection exception, the NMI is unmasked before the general-protection exception handler is invoked." QEMU does not reset NMI-blocking in such situation. This patch fixes it. --- target-i386/cc_helper.c | 5 +++++ target-i386/helper.h | 1 + target-i386/translate.c | 1 + 3 files changed, 7 insertions(+) diff --git a/target-i386/cc_helper.c b/target-i386/cc_helper.c index 83af223..74851ae 100644 --- a/target-i386/cc_helper.c +++ b/target-i386/cc_helper.c @@ -383,3 +383,8 @@ void helper_sti_vm(CPUX86State *env) } } #endif + +void helper_reset_nmi_blocking(CPUX86State *env) +{ + env->hflags2 &= ~HF2_NMI_MASK; +} \ No newline at end of file diff --git a/target-i386/helper.h b/target-i386/helper.h index 1320edc..7718d2f 100644 --- a/target-i386/helper.h +++ b/target-i386/helper.h @@ -70,6 +70,7 @@ DEF_HELPER_1(cli, void, env) DEF_HELPER_1(sti, void, env) DEF_HELPER_1(clac, void, env) DEF_HELPER_1(stac, void, env) +DEF_HELPER_1(reset_nmi_blocking, void, env) DEF_HELPER_3(boundw, void, env, tl, int) DEF_HELPER_3(boundl, void, env, tl, int) DEF_HELPER_1(rsm, void, env) diff --git a/target-i386/translate.c b/target-i386/translate.c index f010022..c409baf 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -6319,6 +6319,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, set_cc_op(s, CC_OP_EFLAGS); } else if (s->vm86) { if (s->iopl != 3) { + gen_helper_reset_nmi_blocking(cpu_env); gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1)); -- 1.8.4.msysgit.0 Best regards, Dmitry Poletaev.