From patchwork Sun Mar 24 18:44:48 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 2327051 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id AA27D3FC54 for ; Sun, 24 Mar 2013 18:45:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754464Ab3CXSo7 (ORCPT ); Sun, 24 Mar 2013 14:44:59 -0400 Received: from mout.web.de ([212.227.15.3]:63563 "EHLO mout.web.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753558Ab3CXSo6 (ORCPT ); Sun, 24 Mar 2013 14:44:58 -0400 Received: from localhost.localdomain ([95.157.56.37]) by smtp.web.de (mrweb002) with ESMTPSA (Nemesis) id 0Lxx0G-1Uneto1jcK-015XXk; Sun, 24 Mar 2013 19:44:56 +0100 From: Jan Kiszka To: Gleb Natapov , Marcelo Tosatti Cc: kvm , Paolo Bonzini , Nadav Har'El Subject: [PATCH v3 5/5] KVM: nVMX: Fix conditions for NMI injection Date: Sun, 24 Mar 2013 19:44:48 +0100 Message-Id: X-Mailer: git-send-email 1.7.3.4 In-Reply-To: References: In-Reply-To: References: X-Provags-ID: V02:K0:u1IZY+pkoWENRGnq2PBs/zCF3vmB1aZmxqb51L40a4e EM72ekuw/pV7EnmdBQ6hPCrEyjcCDWr6j0ZT33okR2NsiqIx04 T76b/p+SuTiQ9iL0LUXS70UeprKEUGHjaPna4nC2mHOb1wCsHb pxIC1TYLhMfwCPztxp0q9lYJUq7jKfyDZHzeB90deGki0BNrsr wDFze6ufMp1933Q4I9qzg== Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org From: Jan Kiszka The logic for checking if interrupts can be injected has to be applied also on NMIs. The difference is that if NMI interception is on these events are consumed and blocked by the VM exit. Signed-off-by: Jan Kiszka --- arch/x86/kvm/vmx.c | 35 +++++++++++++++++++++++++++++++++++ 1 files changed, 35 insertions(+), 0 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 30aa198..c01d487 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -4190,6 +4190,12 @@ static bool nested_exit_on_intr(struct kvm_vcpu *vcpu) PIN_BASED_EXT_INTR_MASK; } +static bool nested_exit_on_nmi(struct kvm_vcpu *vcpu) +{ + return get_vmcs12(vcpu)->pin_based_vm_exec_control & + PIN_BASED_NMI_EXITING; +} + static void enable_irq_window(struct kvm_vcpu *vcpu) { u32 cpu_based_vm_exec_control; @@ -4315,6 +4321,35 @@ static void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked) static int vmx_nmi_allowed(struct kvm_vcpu *vcpu) { + if (is_guest_mode(vcpu)) { + struct vmcs12 *vmcs12 = get_vmcs12(vcpu); + + if (to_vmx(vcpu)->nested.nested_run_pending || + vmcs_read32(GUEST_ACTIVITY_STATE) == + GUEST_ACTIVITY_WAIT_SIPI) + return 0; + if (nested_exit_on_nmi(vcpu)) { + /* + * Check if the idt_vectoring_info_field is free. We + * cannot raise EXIT_REASON_EXCEPTION_NMI if it isn't. + */ + if (vmcs12->idt_vectoring_info_field & + VECTORING_INFO_VALID_MASK) + return 0; + nested_vmx_vmexit(vcpu); + vmcs12->vm_exit_reason = EXIT_REASON_EXCEPTION_NMI; + vmcs12->vm_exit_intr_info = NMI_VECTOR | + INTR_TYPE_NMI_INTR | INTR_INFO_VALID_MASK; + /* + * The NMI-triggered VM exit counts as injection: + * clear this one and block further NMIs. + */ + vcpu->arch.nmi_pending = 0; + vmx_set_nmi_mask(vcpu, true); + return 0; + } + } + if (!cpu_has_virtual_nmis() && to_vmx(vcpu)->soft_vnmi_blocked) return 0;