From patchwork Sun Apr 14 10:12: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: 2441651 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 03E663FD1A for ; Sun, 14 Apr 2013 10:13:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751094Ab3DNKNN (ORCPT ); Sun, 14 Apr 2013 06:13:13 -0400 Received: from mout.web.de ([212.227.15.4]:57537 "EHLO mout.web.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751362Ab3DNKNB (ORCPT ); Sun, 14 Apr 2013 06:13:01 -0400 Received: from localhost.localdomain ([95.157.56.37]) by smtp.web.de (mrweb001) with ESMTPSA (Nemesis) id 0LbZpT-1Up9Po3prX-00lBK9; Sun, 14 Apr 2013 12:12:56 +0200 From: Jan Kiszka To: Gleb Natapov , Marcelo Tosatti Cc: kvm , Paolo Bonzini , Nadav Har'El Subject: [PATCH v4 4/6] KVM: nVMX: Fix conditions for interrupt injection Date: Sun, 14 Apr 2013 12:12:48 +0200 Message-Id: X-Mailer: git-send-email 1.7.3.4 In-Reply-To: References: In-Reply-To: References: X-Provags-ID: V02:K0:UJVeGAa+AypLrwfecrAughgjzGB19ljmH9CrJEp1DLZ yzZCY1sK4+i6dSvGwcrGwlIxk2ko75mRoiCQ2RPM+wF/gHJqBR Af7LYGiwvnMcBgbpnK0fBrjOX0F8QA5X4VIlKs87zIKGk+pll7 3WMlFYvh04Yh0csrHCFmdz+em9uGR1MZMPIuG1P1kmi30YyEj1 rD/OktGp4wks2gEKWe3+Q== Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org From: Jan Kiszka If we are entering guest mode, we do not want L0 to interrupt this vmentry with all its side effects on the vmcs. Therefore, injection shall be disallowed during L1->L2 transitions, as in the previous version. However, this check is conceptually independent of nested_exit_on_intr, so decouple it. If L1 traps external interrupts, we can kick the guest from L2 to L1, also just like the previous code worked. But we no longer need to consider L1's idt_vectoring_info_field. It will always be empty at this point. Instead, if L2 has pending events, those are now found in the architectural queues and will, thus, prevent vmx_interrupt_allowed from being called at all. Signed-off-by: Jan Kiszka --- arch/x86/kvm/vmx.c | 20 ++++++++++++-------- 1 files changed, 12 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 24680a9..56e7519 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -4325,16 +4325,20 @@ static int vmx_nmi_allowed(struct kvm_vcpu *vcpu) static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu) { - if (is_guest_mode(vcpu) && nested_exit_on_intr(vcpu)) { + if (is_guest_mode(vcpu)) { struct vmcs12 *vmcs12 = get_vmcs12(vcpu); - if (to_vmx(vcpu)->nested.nested_run_pending || - (vmcs12->idt_vectoring_info_field & - VECTORING_INFO_VALID_MASK)) + + if (to_vmx(vcpu)->nested.nested_run_pending) return 0; - nested_vmx_vmexit(vcpu); - vmcs12->vm_exit_reason = EXIT_REASON_EXTERNAL_INTERRUPT; - vmcs12->vm_exit_intr_info = 0; - /* fall through to normal code, but now in L1, not L2 */ + if (nested_exit_on_intr(vcpu)) { + nested_vmx_vmexit(vcpu); + vmcs12->vm_exit_reason = + EXIT_REASON_EXTERNAL_INTERRUPT; + vmcs12->vm_exit_intr_info = 0; + /* + * fall through to normal code, but now in L1, not L2 + */ + } } return (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF) &&