From owner-svn-src-projects@FreeBSD.ORG Wed Oct 24 02:54:22 2012 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 59C059B6; Wed, 24 Oct 2012 02:54:22 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 3FFE08FC0C; Wed, 24 Oct 2012 02:54:22 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q9O2sMfp022845; Wed, 24 Oct 2012 02:54:22 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q9O2sLl9022839; Wed, 24 Oct 2012 02:54:21 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201210240254.q9O2sLl9022839@svn.freebsd.org> From: Neel Natu Date: Wed, 24 Oct 2012 02:54:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r241982 - in projects/bhyve/sys/amd64: include vmm vmm/amd 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: Wed, 24 Oct 2012 02:54:22 -0000 Author: neel Date: Wed Oct 24 02:54:21 2012 New Revision: 241982 URL: http://svn.freebsd.org/changeset/base/241982 Log: Maintain state regarding NMI delivery to guest vcpu in VT-x independent manner. Also add a stats counter to count the number of NMIs delivered per vcpu. Obtained from: NetApp Modified: projects/bhyve/sys/amd64/include/vmm.h projects/bhyve/sys/amd64/vmm/amd/amdv.c projects/bhyve/sys/amd64/vmm/intel/vmx.c projects/bhyve/sys/amd64/vmm/intel/vmx.h projects/bhyve/sys/amd64/vmm/vmm.c Modified: projects/bhyve/sys/amd64/include/vmm.h ============================================================================== --- projects/bhyve/sys/amd64/include/vmm.h Wed Oct 24 02:32:06 2012 (r241981) +++ projects/bhyve/sys/amd64/include/vmm.h Wed Oct 24 02:54:21 2012 (r241982) @@ -63,7 +63,6 @@ typedef int (*vmi_set_desc_t)(void *vmi, typedef int (*vmi_inject_event_t)(void *vmi, int vcpu, int type, int vector, uint32_t code, int code_valid); -typedef int (*vmi_inject_nmi_t)(void *vmi, int vcpu); typedef int (*vmi_get_cap_t)(void *vmi, int vcpu, int num, int *retval); typedef int (*vmi_set_cap_t)(void *vmi, int vcpu, int num, int val); @@ -81,7 +80,6 @@ struct vmm_ops { vmi_get_desc_t vmgetdesc; vmi_set_desc_t vmsetdesc; vmi_inject_event_t vminject; - vmi_inject_nmi_t vmnmi; vmi_get_cap_t vmgetcap; vmi_set_cap_t vmsetcap; }; @@ -110,6 +108,8 @@ int vm_run(struct vm *vm, struct vm_run int vm_inject_event(struct vm *vm, int vcpu, int type, int vector, uint32_t error_code, int error_code_valid); int vm_inject_nmi(struct vm *vm, int vcpu); +int vm_nmi_pending(struct vm *vm, int vcpuid); +void vm_nmi_clear(struct vm *vm, int vcpuid); uint64_t *vm_guest_msrs(struct vm *vm, int cpu); struct vlapic *vm_lapic(struct vm *vm, int cpu); int vm_get_capability(struct vm *vm, int vcpu, int type, int *val); Modified: projects/bhyve/sys/amd64/vmm/amd/amdv.c ============================================================================== --- projects/bhyve/sys/amd64/vmm/amd/amdv.c Wed Oct 24 02:32:06 2012 (r241981) +++ projects/bhyve/sys/amd64/vmm/amd/amdv.c Wed Oct 24 02:54:21 2012 (r241982) @@ -136,14 +136,6 @@ amdv_inject_event(void *vmi, int vcpu, i } static int -amdv_nmi(void *arg, int vcpu) -{ - - printf("amdv_nmi: not implemented\n"); - return (EINVAL); -} - -static int amdv_getcap(void *arg, int vcpu, int type, int *retval) { @@ -172,7 +164,6 @@ struct vmm_ops vmm_ops_amd = { amdv_getdesc, amdv_setdesc, amdv_inject_event, - amdv_nmi, amdv_getcap, amdv_setcap }; Modified: projects/bhyve/sys/amd64/vmm/intel/vmx.c ============================================================================== --- projects/bhyve/sys/amd64/vmm/intel/vmx.c Wed Oct 24 02:32:06 2012 (r241981) +++ projects/bhyve/sys/amd64/vmm/intel/vmx.c Wed Oct 24 02:54:21 2012 (r241982) @@ -751,7 +751,6 @@ vmx_vminit(struct vm *vm) vmx->cap[i].set = 0; vmx->cap[i].proc_ctls = procbased_ctls; - vmx->state[i].request_nmi = 0; vmx->state[i].lastcpu = -1; vmx->state[i].vpid = vpid; @@ -940,7 +939,7 @@ vmx_inject_nmi(struct vmx *vmx, int vcpu uint64_t info, interruptibility; /* Bail out if no NMI requested */ - if (vmx->state[vcpu].request_nmi == 0) + if (!vm_nmi_pending(vmx->vm, vcpu)) return (0); error = vmread(VMCS_GUEST_INTERRUPTIBILITY, &interruptibility); @@ -965,7 +964,7 @@ vmx_inject_nmi(struct vmx *vmx, int vcpu VMM_CTR0(vmx->vm, vcpu, "Injecting vNMI"); /* Clear the request */ - vmx->state[vcpu].request_nmi = 0; + vm_nmi_clear(vmx->vm, vcpu); return (1); nmiblocked: @@ -1696,16 +1695,6 @@ vmx_inject(void *arg, int vcpu, int type } static int -vmx_nmi(void *arg, int vcpu) -{ - struct vmx *vmx = arg; - - atomic_set_int(&vmx->state[vcpu].request_nmi, 1); - - return (0); -} - -static int vmx_getcap(void *arg, int vcpu, int type, int *retval) { struct vmx *vmx = arg; @@ -1843,7 +1832,6 @@ struct vmm_ops vmm_ops_intel = { vmx_getdesc, vmx_setdesc, vmx_inject, - vmx_nmi, vmx_getcap, vmx_setcap }; Modified: projects/bhyve/sys/amd64/vmm/intel/vmx.h ============================================================================== --- projects/bhyve/sys/amd64/vmm/intel/vmx.h Wed Oct 24 02:32:06 2012 (r241981) +++ projects/bhyve/sys/amd64/vmm/intel/vmx.h Wed Oct 24 02:54:21 2012 (r241982) @@ -76,7 +76,6 @@ struct vmxcap { }; struct vmxstate { - int request_nmi; int lastcpu; /* host cpu that this 'vcpu' last ran on */ uint16_t vpid; }; Modified: projects/bhyve/sys/amd64/vmm/vmm.c ============================================================================== --- projects/bhyve/sys/amd64/vmm/vmm.c Wed Oct 24 02:32:06 2012 (r241981) +++ projects/bhyve/sys/amd64/vmm/vmm.c Wed Oct 24 02:54:21 2012 (r241982) @@ -77,6 +77,7 @@ struct vcpu { void *stats; struct vm_exit exitinfo; enum x2apic_state x2apic_state; + int nmi_pending; }; #define VCPU_F_PINNED 0x0001 @@ -137,8 +138,6 @@ static struct vmm_ops *ops; (ops != NULL ? (*ops->vmsetdesc)(vmi, vcpu, num, desc) : ENXIO) #define VMINJECT(vmi, vcpu, type, vec, ec, ecv) \ (ops != NULL ? (*ops->vminject)(vmi, vcpu, type, vec, ec, ecv) : ENXIO) -#define VMNMI(vmi, vcpu) \ - (ops != NULL ? (*ops->vmnmi)(vmi, vcpu) : ENXIO) #define VMGETCAP(vmi, vcpu, num, retval) \ (ops != NULL ? (*ops->vmgetcap)(vmi, vcpu, num, retval) : ENXIO) #define VMSETCAP(vmi, vcpu, num, val) \ @@ -710,17 +709,51 @@ vm_inject_event(struct vm *vm, int vcpui return (VMINJECT(vm->cookie, vcpuid, type, vector, code, code_valid)); } +VMM_STAT_DEFINE(VCPU_NMI_COUNT, "number of NMIs delivered to vcpu"); + int -vm_inject_nmi(struct vm *vm, int vcpu) +vm_inject_nmi(struct vm *vm, int vcpuid) { - int error; + struct vcpu *vcpu; - if (vcpu < 0 || vcpu >= VM_MAXCPU) + if (vcpuid < 0 || vcpuid >= VM_MAXCPU) return (EINVAL); - error = VMNMI(vm->cookie, vcpu); - vm_interrupt_hostcpu(vm, vcpu); - return (error); + vcpu = &vm->vcpu[vcpuid]; + + vcpu->nmi_pending = 1; + vm_interrupt_hostcpu(vm, vcpuid); + return (0); +} + +int +vm_nmi_pending(struct vm *vm, int vcpuid) +{ + struct vcpu *vcpu; + + if (vcpuid < 0 || vcpuid >= VM_MAXCPU) + panic("vm_nmi_pending: invalid vcpuid %d", vcpuid); + + vcpu = &vm->vcpu[vcpuid]; + + return (vcpu->nmi_pending); +} + +void +vm_nmi_clear(struct vm *vm, int vcpuid) +{ + struct vcpu *vcpu; + + if (vcpuid < 0 || vcpuid >= VM_MAXCPU) + panic("vm_nmi_pending: invalid vcpuid %d", vcpuid); + + vcpu = &vm->vcpu[vcpuid]; + + if (vcpu->nmi_pending == 0) + panic("vm_nmi_clear: inconsistent nmi_pending state"); + + vcpu->nmi_pending = 0; + vmm_stat_incr(vm, vcpuid, VCPU_NMI_COUNT, 1); } int