From mboxrd@z Thu Jan 1 00:00:00 1970 From: Gleb Natapov Subject: Re: NMI Injection to Guest Date: Sun, 2 Aug 2009 12:15:39 +0300 Message-ID: <20090802091539.GT30449@redhat.com> References: <6d8082040907251346h79430f03nb31e762da29c665d@mail.gmail.com> <20090726054705.GI7928@redhat.com> <6d8082040907261225u6c5a7012jc9c3492e29e7feb1@mail.gmail.com> <20090727051740.GA20501@redhat.com> <6d8082040907300624n212fab47h1a5fac17f13c6106@mail.gmail.com> <6d8082040908010836ka77f4c9hbffc94468448cd3d@mail.gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: kvm@vger.kernel.org To: Jiaqing Du Return-path: Received: from mx2.redhat.com ([66.187.237.31]:40758 "EHLO mx2.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752485AbZHBJQo (ORCPT ); Sun, 2 Aug 2009 05:16:44 -0400 Content-Disposition: inline In-Reply-To: <6d8082040908010836ka77f4c9hbffc94468448cd3d@mail.gmail.com> Sender: kvm-owner@vger.kernel.org List-ID: On Sat, Aug 01, 2009 at 05:36:16PM +0200, Jiaqing Du wrote: > Hi Gleb, > > Another problem on AMD processors. > > After each vm-exit, I need to check if this vm-exit is due to NMI. For > vmx.c, I add the check in vmx_complete_interrupts(). > > The code snippet is: > > 3539 if ((exit_intr_info & INTR_INFO_INTR_TYPE_MASK) == > INTR_TYPE_NMI_INTR && > 3540 (exit_intr_info & INTR_INFO_VALID_MASK)) { > 3541 > 3542 printk(KERN_INFO "kvm-oprofile: vm exit due to NMI.\n"); > 3543 > 3544 /* indicate vm-exit due to conter overflow */ > 3545 vcpu->vm_exit_on_cntr_overflow = 1; > 3546 } > > This works on Intel chips. > > I did the similar check in svm_complete_interrupts(). > > 2501 static void svm_complete_interrupts(struct vcpu_svm *svm) > 2502 { > 2503 u8 vector; > 2504 int type; > 2505 u32 exitintinfo = svm->vmcb->control.exit_int_info; > 2506 struct kvm_vcpu *vcpu = &svm->vcpu; > 2507 > 2508 if (svm->vcpu.arch.hflags & HF_IRET_MASK) > 2509 svm->vcpu.arch.hflags &= ~(HF_NMI_MASK | HF_IRET_MASK); > 2510 > 2511 svm->vcpu.arch.nmi_injected = false; > 2512 kvm_clear_exception_queue(&svm->vcpu); > 2513 kvm_clear_interrupt_queue(&svm->vcpu); > 2514 > 2515 if (!(exitintinfo & SVM_EXITINTINFO_VALID)) > 2516 return; > 2517 > 2518 vector = exitintinfo & SVM_EXITINTINFO_VEC_MASK; > 2519 type = exitintinfo & SVM_EXITINTINFO_TYPE_MASK; > 2520 > 2521 /* kvm-oprofile */ > 2522 if (type == SVM_EXITINTINFO_TYPE_NMI) { > 2523 > 2524 printk(KERN_INFO "kvm-oprofile: > counter_overflowed & vm exit.\n"); > 2525 vcpu->vm_exit_on_cntr_overflow = 1; > 2526 } > > However, this part (2522 to 2526) never got executed. By using qemu > monitor, I managed to inject NMI to the guests. But this check, after > vm-exit due to NMI, does not succeed. > > The check on AMD is very different from the check on Intel. On AMD you are checking for IDT access fault during NMI delivery and on Intel you are checking if the last vmexit was due to NMI delivered to a CPU by HW while guest was running. On AMD nmi_interception() is called in this case. And since MNI interception intercepts only HW NMIs not NMIs that hypervisor injects your test (using qemu monitor to inject NMI) is also not valid. -- Gleb.