From owner-svn-src-all@FreeBSD.ORG Wed Jan 22 04:03:12 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 22425780; Wed, 22 Jan 2014 04:03:12 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 0E94F1979; Wed, 22 Jan 2014 04:03:12 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id s0M43BHw036094; Wed, 22 Jan 2014 04:03:11 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.7/8.14.7/Submit) id s0M43B9M036090; Wed, 22 Jan 2014 04:03:11 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201401220403.s0M43B9M036090@svn.freebsd.org> From: Neel Natu Date: Wed, 22 Jan 2014 04:03:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r261001 - in head/sys/amd64/vmm: . intel X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 22 Jan 2014 04:03:12 -0000 Author: neel Date: Wed Jan 22 04:03:11 2014 New Revision: 261001 URL: http://svnweb.freebsd.org/changeset/base/261001 Log: Handle a VM-exit due to a NMI properly by vectoring to the host's NMI handler via a software interrupt. This is safe to do because the logical processor is already cognizant of the NMI and further NMIs are blocked until the host's NMI handler executes "iret". Modified: head/sys/amd64/vmm/intel/vmx.c head/sys/amd64/vmm/vmm_stat.c head/sys/amd64/vmm/vmm_stat.h Modified: head/sys/amd64/vmm/intel/vmx.c ============================================================================== --- head/sys/amd64/vmm/intel/vmx.c Wed Jan 22 01:57:52 2014 (r261000) +++ head/sys/amd64/vmm/intel/vmx.c Wed Jan 22 04:03:11 2014 (r261001) @@ -1491,6 +1491,7 @@ vmx_exit_process(struct vmx *vmx, int vc bool retu; CTASSERT((PINBASED_CTLS_ONE_SETTING & PINBASED_VIRTUAL_NMI) != 0); + CTASSERT((PINBASED_CTLS_ONE_SETTING & PINBASED_NMI_EXITING) != 0); handled = 0; vmxctx = &vmx->ctx[vcpu]; @@ -1643,9 +1644,11 @@ vmx_exit_process(struct vmx *vmx, int vc handled = vmx_handle_cpuid(vmx->vm, vcpu, vmxctx); break; case EXIT_REASON_EXCEPTION: + vmm_stat_incr(vmx->vm, vcpu, VMEXIT_EXCEPTION, 1); intr_info = vmcs_read(VMCS_EXIT_INTR_INFO); KASSERT((intr_info & VMCS_INTR_VALID) != 0, ("VM exit interruption info invalid: %#x", intr_info)); + /* * If Virtual NMIs control is 1 and the VM-exit is due to a * fault encountered during the execution of IRET then we must @@ -1658,6 +1661,21 @@ vmx_exit_process(struct vmx *vmx, int vc (intr_info & 0xff) != IDT_DF && (intr_info & EXIT_QUAL_NMIUDTI) != 0) vmx_restore_nmi_blocking(vmx, vcpu); + + /* + * If the NMI-exiting VM execution control is set to '1' + * then an NMI in non-root operation causes a VM-exit. + * NMI blocking is in effect for this logical processor so + * it is sufficient to simply vector to the NMI handler via + * a software interrupt. + */ + if ((intr_info & VMCS_INTR_T_MASK) == VMCS_INTR_T_NMI) { + KASSERT((intr_info & 0xff) == IDT_NMI, ("VM exit due " + "to NMI has invalid vector: %#x", intr_info)); + VCPU_CTR0(vmx->vm, vcpu, "Vectoring to NMI handler"); + __asm __volatile("int $2"); + return (1); + } break; case EXIT_REASON_EPT_FAULT: vmm_stat_incr(vmx->vm, vcpu, VMEXIT_EPT_FAULT, 1); @@ -1728,6 +1746,8 @@ vmx_exit_process(struct vmx *vmx, int vc */ vmexit->exitcode = VM_EXITCODE_VMX; vmexit->u.vmx.status = VM_SUCCESS; + vmexit->u.vmx.inst_type = 0; + vmexit->u.vmx.inst_error = 0; } else { /* * The exitcode and collateral have been populated. Modified: head/sys/amd64/vmm/vmm_stat.c ============================================================================== --- head/sys/amd64/vmm/vmm_stat.c Wed Jan 22 01:57:52 2014 (r261000) +++ head/sys/amd64/vmm/vmm_stat.c Wed Jan 22 04:03:11 2014 (r261001) @@ -151,3 +151,4 @@ VMM_STAT(VMEXIT_UNKNOWN, "number of vm e VMM_STAT(VMEXIT_ASTPENDING, "number of times astpending at exit"); VMM_STAT(VMEXIT_USERSPACE, "number of vm exits handled in userspace"); VMM_STAT(VMEXIT_RENDEZVOUS, "number of times rendezvous pending at exit"); +VMM_STAT(VMEXIT_EXCEPTION, "number of vm exits due to exceptions"); Modified: head/sys/amd64/vmm/vmm_stat.h ============================================================================== --- head/sys/amd64/vmm/vmm_stat.h Wed Jan 22 01:57:52 2014 (r261000) +++ head/sys/amd64/vmm/vmm_stat.h Wed Jan 22 04:03:11 2014 (r261001) @@ -121,4 +121,5 @@ VMM_STAT_DECLARE(VMEXIT_UNKNOWN); VMM_STAT_DECLARE(VMEXIT_ASTPENDING); VMM_STAT_DECLARE(VMEXIT_USERSPACE); VMM_STAT_DECLARE(VMEXIT_RENDEZVOUS); +VMM_STAT_DECLARE(VMEXIT_EXCEPTION); #endif