diff options
Diffstat (limited to 'target-i386')
-rw-r--r-- | target-i386/cpu.h | 2 | ||||
-rw-r--r-- | target-i386/exec.h | 5 | ||||
-rw-r--r-- | target-i386/helper.c | 2 |
3 files changed, 7 insertions, 2 deletions
diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 1c49b3691b..152b673ee9 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -148,6 +148,7 @@ #define HF_SMM_SHIFT 19 /* CPU in SMM mode */ #define HF_GIF_SHIFT 20 /* if set CPU takes interrupts */ #define HF_HIF_SHIFT 21 /* shadow copy of IF_MASK when in SVM */ +#define HF_NMI_SHIFT 22 /* CPU serving NMI */ #define HF_CPL_MASK (3 << HF_CPL_SHIFT) #define HF_SOFTMMU_MASK (1 << HF_SOFTMMU_SHIFT) @@ -167,6 +168,7 @@ #define HF_SMM_MASK (1 << HF_SMM_SHIFT) #define HF_GIF_MASK (1 << HF_GIF_SHIFT) #define HF_HIF_MASK (1 << HF_HIF_SHIFT) +#define HF_NMI_MASK (1 << HF_NMI_SHIFT) #define CR0_PE_MASK (1 << 0) #define CR0_MP_MASK (1 << 1) diff --git a/target-i386/exec.h b/target-i386/exec.h index 37fcdc01b7..11d12c9b00 100644 --- a/target-i386/exec.h +++ b/target-i386/exec.h @@ -593,8 +593,9 @@ static inline int cpu_halted(CPUState *env) { if (!(env->hflags & HF_HALTED_MASK)) return 0; /* disable halt condition */ - if ((env->interrupt_request & CPU_INTERRUPT_HARD) && - (env->eflags & IF_MASK)) { + if (((env->interrupt_request & CPU_INTERRUPT_HARD) && + (env->eflags & IF_MASK)) || + (env->interrupt_request & CPU_INTERRUPT_NMI)) { env->hflags &= ~HF_HALTED_MASK; return 0; } diff --git a/target-i386/helper.c b/target-i386/helper.c index 69c2051f7c..b2c829926c 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -2383,6 +2383,7 @@ void helper_iret_real(int shift) if (shift == 0) eflags_mask &= 0xffff; load_eflags(new_eflags, eflags_mask); + env->hflags &= ~HF_NMI_MASK; } static inline void validate_seg(int seg_reg, int cpl) @@ -2634,6 +2635,7 @@ void helper_iret_protected(int shift, int next_eip) } else { helper_ret_protected(shift, 1, 0); } + env->hflags &= ~HF_NMI_MASK; #ifdef USE_KQEMU if (kqemu_is_ok(env)) { CC_OP = CC_OP_EFLAGS; |