From mboxrd@z Thu Jan 1 00:00:00 1970 From: Gleb Natapov Subject: Re: [PATCH] KVM: VMX: Translate interrupt shadow when waiting on NMI window Date: Tue, 16 Feb 2010 12:00:58 +0200 Message-ID: <20100216100057.GC2995@redhat.com> References: <4B7A625C.4070803@siemens.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: Avi Kivity , Marcelo Tosatti , kvm To: Jan Kiszka Return-path: Received: from mx1.redhat.com ([209.132.183.28]:64441 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756868Ab0BPKBD (ORCPT ); Tue, 16 Feb 2010 05:01:03 -0500 Content-Disposition: inline In-Reply-To: <4B7A625C.4070803@siemens.com> Sender: kvm-owner@vger.kernel.org List-ID: On Tue, Feb 16, 2010 at 10:16:12AM +0100, Jan Kiszka wrote: > Found while browsing Xen code: While we assume that the STI interrupt > shadow also inplies virtual NMI blocking, some processors may have a > different opinion (SDM 3: 22.3). To avoid misunderstandings that would > cause endless VM entry attempts, translate STI into MOV SS blocking when > requesting the NMI window. > Why not just remove "block by STI" check in vmx_nmi_allowed()? IIRC this is documented that on some CPUs STI does not block NMI. > Signed-off-by: Jan Kiszka > --- > > arch/x86/kvm/vmx.c | 15 +++++++++++++++ > 1 files changed, 15 insertions(+), 0 deletions(-) > > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c > index 14873b9..474f720 100644 > --- a/arch/x86/kvm/vmx.c > +++ b/arch/x86/kvm/vmx.c > @@ -2614,12 +2614,27 @@ static void enable_irq_window(struct kvm_vcpu *vcpu) > static void enable_nmi_window(struct kvm_vcpu *vcpu) > { > u32 cpu_based_vm_exec_control; > + u32 interruptibility; > > if (!cpu_has_virtual_nmis()) { > enable_irq_window(vcpu); > return; > } > > + /* > + * SDM 3: 22.3 (June 2009) > + * "A logical processor may also prevent such a VM exit [NMI-window > + * exit] if there is blocking of events by STI." > + * So better convert STI blocking into MOV SS to avoid premature VM > + * exits that would end up in an endless loop. > + */ > + interruptibility = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO); > + if (interruptibility & GUEST_INTR_STATE_STI) { > + interruptibility &= ~GUEST_INTR_STATE_STI; > + interruptibility |= GUEST_INTR_STATE_MOV_SS; > + vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, interruptibility); > + } > + > cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL); > cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_NMI_PENDING; > vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); -- Gleb.