Date: Wed, 22 Jan 2014 04:03:11 +0000 (UTC) From: Neel Natu <neel@FreeBSD.org> 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 Message-ID: <201401220403.s0M43B9M036090@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201401220403.s0M43B9M036090>