From owner-svn-src-projects@FreeBSD.ORG Thu Aug 1 19:37:12 2013 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 32F9FB7D; Thu, 1 Aug 2013 19:37:12 +0000 (UTC) (envelope-from neel@FreeBSD.org) 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 1FF1126B8; Thu, 1 Aug 2013 19:37: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 r71JbBnt015445; Thu, 1 Aug 2013 19:37:11 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r71JbBID015443; Thu, 1 Aug 2013 19:37:11 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201308011937.r71JbBID015443@svn.freebsd.org> From: Neel Natu Date: Thu, 1 Aug 2013 19:37:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r253864 - projects/bhyve_npt_pmap/sys/amd64/vmm/intel X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 01 Aug 2013 19:37:12 -0000 Author: neel Date: Thu Aug 1 19:37:11 2013 New Revision: 253864 URL: http://svnweb.freebsd.org/changeset/base/253864 Log: Deal with VM exits during event injection properly by re-injecting the event on the next VM entry. Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmcs.h projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmcs.h ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmcs.h Thu Aug 1 19:30:10 2013 (r253863) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmcs.h Thu Aug 1 19:37:11 2013 (r253864) @@ -68,6 +68,8 @@ uint64_t vmcs_read(uint32_t encoding); #define vmcs_guest_cr3() vmcs_read(VMCS_GUEST_CR3) #define vmcs_gpa() vmcs_read(VMCS_GUEST_PHYSICAL_ADDRESS) #define vmcs_gla() vmcs_read(VMCS_GUEST_LINEAR_ADDRESS) +#define vmcs_idt_vectoring_info() vmcs_read(VMCS_IDT_VECTORING_INFO) +#define vmcs_idt_vectoring_err() vmcs_read(VMCS_IDT_VECTORING_ERROR) #endif /* _KERNEL */ @@ -314,6 +316,12 @@ uint64_t vmcs_read(uint32_t encoding); #define VMCS_INTERRUPTION_INFO_NMI (2 << 8) /* + * VMCS IDT-Vectoring information fields + */ +#define VMCS_IDT_VEC_VALID (1 << 31) +#define VMCS_IDT_VEC_ERRCODE_VALID (1 << 11) + +/* * VMCS Guest interruptibility field */ #define VMCS_INTERRUPTIBILITY_STI_BLOCKING (1 << 0) Modified: projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c ============================================================================== --- projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c Thu Aug 1 19:30:10 2013 (r253863) +++ projects/bhyve_npt_pmap/sys/amd64/vmm/intel/vmx.c Thu Aug 1 19:37:11 2013 (r253864) @@ -167,9 +167,6 @@ static int cap_pause_exit; static int cap_unrestricted_guest; static int cap_monitor_trap; -/* statistics */ -static VMM_STAT_INTEL(VMEXIT_HLT_IGNORED, "number of times hlt was ignored"); - #ifdef KTR static const char * exit_reason_to_str(int reason) @@ -1239,18 +1236,47 @@ vmx_exit_process(struct vmx *vmx, int vc int error, handled; struct vmcs *vmcs; struct vmxctx *vmxctx; - uint32_t eax, ecx, edx; - uint64_t qual, gpa, intr_info; + uint32_t eax, ecx, edx, idtvec_info, idtvec_err, reason; + uint64_t qual, gpa; handled = 0; vmcs = &vmx->vmcs[vcpu]; vmxctx = &vmx->ctx[vcpu]; qual = vmexit->u.vmx.exit_qualification; + reason = vmexit->u.vmx.exit_reason; vmexit->exitcode = VM_EXITCODE_BOGUS; vmm_stat_incr(vmx->vm, vcpu, VMEXIT_COUNT, 1); - switch (vmexit->u.vmx.exit_reason) { + /* + * VM exits that could be triggered during event injection on the + * previous VM entry need to be handled specially by re-injecting + * the event. + * + * See "Information for VM Exits During Event Delivery" in Intel SDM + * for details. + */ + switch (reason) { + case EXIT_REASON_EPT_FAULT: + case EXIT_REASON_EPT_MISCONFIG: + case EXIT_REASON_APIC: + case EXIT_REASON_TASK_SWITCH: + case EXIT_REASON_EXCEPTION: + idtvec_info = vmcs_idt_vectoring_info(); + if (idtvec_info & VMCS_IDT_VEC_VALID) { + idtvec_info &= ~(1 << 12); /* clear undefined bit */ + vmwrite(VMCS_ENTRY_INTR_INFO, idtvec_info); + if (idtvec_info & VMCS_IDT_VEC_ERRCODE_VALID) { + idtvec_err = vmcs_idt_vectoring_err(); + vmwrite(VMCS_ENTRY_EXCEPTION_ERROR, idtvec_err); + } + vmwrite(VMCS_ENTRY_INST_LENGTH, vmexit->inst_length); + } + default: + break; + } + + switch (reason) { case EXIT_REASON_CR_ACCESS: vmm_stat_incr(vmx->vm, vcpu, VMEXIT_CR_ACCESS, 1); handled = vmx_emulate_cr_access(vmx, vcpu, qual); @@ -1281,19 +1307,7 @@ vmx_exit_process(struct vmx *vmx, int vc break; case EXIT_REASON_HLT: vmm_stat_incr(vmx->vm, vcpu, VMEXIT_HLT, 1); - /* - * If there is an event waiting to be injected then there is - * no need to 'hlt'. - */ - error = vmread(VMCS_ENTRY_INTR_INFO, &intr_info); - if (error) - panic("vmx_exit_process: vmread(intrinfo) %d", error); - - if (intr_info & VMCS_INTERRUPTION_INFO_VALID) { - handled = 1; - vmm_stat_incr(vmx->vm, vcpu, VMEXIT_HLT_IGNORED, 1); - } else - vmexit->exitcode = VM_EXITCODE_HLT; + vmexit->exitcode = VM_EXITCODE_HLT; break; case EXIT_REASON_MTF: vmm_stat_incr(vmx->vm, vcpu, VMEXIT_MTRAP, 1);