svn commit: r241982 - in projects/bhyve/sys/amd64: include vmm vmm/amd vmm/intel
Neel Natu
neel at FreeBSD.org
Wed Oct 24 02:54:22 UTC 2012
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
More information about the svn-src-projects
mailing list