From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Jkiu0-0008KU-Ki for qemu-devel@nongnu.org; Sat, 12 Apr 2008 12:48:32 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Jkitv-0008CX-Ke for qemu-devel@nongnu.org; Sat, 12 Apr 2008 12:48:31 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Jkitv-0008CB-0k for qemu-devel@nongnu.org; Sat, 12 Apr 2008 12:48:27 -0400 Received: from fmmailgate03.web.de ([217.72.192.234]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Jkitu-0006Q7-Ac for qemu-devel@nongnu.org; Sat, 12 Apr 2008 12:48:26 -0400 Received: from smtp06.web.de (fmsmtp06.dlan.cinetic.de [172.20.5.172]) by fmmailgate03.web.de (Postfix) with ESMTP id 8F286D6D9602 for ; Sat, 12 Apr 2008 18:48:25 +0200 (CEST) Received: from [88.65.46.55] (helo=[192.168.1.198]) by smtp06.web.de with asmtp (TLSv1:AES256-SHA:256) (WEB.DE 4.109 #226) id 1Jkits-0000Pi-00 for qemu-devel@nongnu.org; Sat, 12 Apr 2008 18:48:24 +0200 Message-ID: <4800E7D7.2050308@web.de> Date: Sat, 12 Apr 2008 18:48:23 +0200 From: Jan Kiszka MIME-Version: 1.0 References: <4800DF6A.5010700@web.de> In-Reply-To: <4800DF6A.5010700@web.de> Content-Type: multipart/mixed; boundary="------------010603060702080702000701" Sender: jan.kiszka@web.de Subject: [Qemu-devel] Re: [PATCH 1/3] x86: Introduce CPU_INTERRUPT_NMI Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org This is a multi-part message in MIME format. --------------010603060702080702000701 Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 7bit Jan Kiszka wrote: > [ This patch obsoletes > http://permalink.gmane.org/gmane.comp.emulators.qemu/22989. ] > > The x86 emulation yet lacks proper NMI support. This patch introduces > CPU_INTERRUPT_NMI and the required handling logic so that hardware > emulation drivers can simply call > > cpu_interrupt(env, CPU_INTERRUPT_NMI); > > to raise an NMI on this arch. > > Signed-off-by: Jan Kiszka > Non-broken patch attached. Sorry. Jan --------------010603060702080702000701 Content-Type: text/x-patch; name="raise-nmi-exception.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="raise-nmi-exception.patch" --- cpu-all.h | 1 + cpu-exec.c | 6 ++++++ target-i386/cpu.h | 2 ++ target-i386/exec.h | 5 +++-- target-i386/helper.c | 2 ++ 5 files changed, 14 insertions(+), 2 deletions(-) Index: b/cpu-all.h =================================================================== --- a/cpu-all.h +++ b/cpu-all.h @@ -753,6 +753,7 @@ extern int code_copy_enabled; #define CPU_INTERRUPT_SMI 0x40 /* (x86 only) SMI interrupt pending */ #define CPU_INTERRUPT_DEBUG 0x80 /* Debug event occured. */ #define CPU_INTERRUPT_VIRQ 0x100 /* virtual interrupt pending. */ +#define CPU_INTERRUPT_NMI 0x200 /* NMI pending. */ void cpu_interrupt(CPUState *s, int mask); void cpu_reset_interrupt(CPUState *env, int mask); Index: b/cpu-exec.c =================================================================== --- a/cpu-exec.c +++ b/cpu-exec.c @@ -444,6 +444,12 @@ int cpu_exec(CPUState *env1) env->interrupt_request &= ~CPU_INTERRUPT_SMI; do_smm_enter(); BREAK_CHAIN; + } else if ((interrupt_request & CPU_INTERRUPT_NMI) && + !(env->hflags & HF_NMI_MASK)) { + env->interrupt_request &= ~CPU_INTERRUPT_NMI; + env->hflags |= HF_NMI_MASK; + do_interrupt(EXCP02_NMI, 0, 0, 0, 1); + BREAK_CHAIN; } else if ((interrupt_request & CPU_INTERRUPT_HARD) && (env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) && !(env->hflags & HF_INHIBIT_IRQ_MASK)) { Index: b/target-i386/cpu.h =================================================================== --- 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) Index: b/target-i386/helper.c =================================================================== --- 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, in } 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; Index: b/target-i386/exec.h =================================================================== --- a/target-i386/exec.h +++ b/target-i386/exec.h @@ -593,8 +593,9 @@ static inline int cpu_halted(CPUState *e 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; } --------------010603060702080702000701--