summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2012-09-24 19:32:24 +0000
committerneel <neel@FreeBSD.org>2012-09-24 19:32:24 +0000
commit34b672cc8af9ef3fbee45a3c9cc28a7e30c9ef16 (patch)
treeac2ec0b166d4669a6efec881955c5dfa87f2d6fe
parentc0caea8c2fc75a9ca5f5a67dd11462ef6542afc2 (diff)
downloadFreeBSD-src-34b672cc8af9ef3fbee45a3c9cc28a7e30c9ef16.zip
FreeBSD-src-34b672cc8af9ef3fbee45a3c9cc28a7e30c9ef16.tar.gz
Stash the 'vm_exit' information in each 'struct vcpu'.
There is no functional change at this time but this paves the way for vm exit handler functions to easily modify the exit reason going forward.
-rw-r--r--sys/amd64/include/vmm.h4
-rw-r--r--sys/amd64/vmm/amd/amdv.c2
-rw-r--r--sys/amd64/vmm/intel/vmx.c5
-rw-r--r--sys/amd64/vmm/vmm.c23
4 files changed, 27 insertions, 7 deletions
diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h
index 1ad01c6..61faf56 100644
--- a/sys/amd64/include/vmm.h
+++ b/sys/amd64/include/vmm.h
@@ -43,8 +43,7 @@ struct vlapic;
typedef int (*vmm_init_func_t)(void);
typedef int (*vmm_cleanup_func_t)(void);
typedef void * (*vmi_init_func_t)(struct vm *vm); /* instance specific apis */
-typedef int (*vmi_run_func_t)(void *vmi, int vcpu, register_t rip,
- struct vm_exit *vmexit);
+typedef int (*vmi_run_func_t)(void *vmi, int vcpu, register_t rip);
typedef void (*vmi_cleanup_func_t)(void *vmi);
typedef int (*vmi_mmap_func_t)(void *vmi, vm_paddr_t gpa, vm_paddr_t hpa,
size_t length, vm_memattr_t attr,
@@ -112,6 +111,7 @@ int vm_get_capability(struct vm *vm, int vcpu, int type, int *val);
int vm_set_capability(struct vm *vm, int vcpu, int type, int val);
void vm_activate_cpu(struct vm *vm, int vcpu);
cpuset_t vm_active_cpus(struct vm *vm);
+struct vm_exit *vm_exitinfo(struct vm *vm, int vcpuid);
/*
* Return 1 if device indicated by bus/slot/func is supposed to be a
diff --git a/sys/amd64/vmm/amd/amdv.c b/sys/amd64/vmm/amd/amdv.c
index 6844cc0..674337d 100644
--- a/sys/amd64/vmm/amd/amdv.c
+++ b/sys/amd64/vmm/amd/amdv.c
@@ -62,7 +62,7 @@ amdv_vminit(struct vm *vm)
}
static int
-amdv_vmrun(void *arg, int vcpu, register_t rip, struct vm_exit *vmexit)
+amdv_vmrun(void *arg, int vcpu, register_t rip)
{
printf("amdv_vmrun: not implemented\n");
diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c
index be58444..88f870c 100644
--- a/sys/amd64/vmm/intel/vmx.c
+++ b/sys/amd64/vmm/intel/vmx.c
@@ -1272,19 +1272,22 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit)
}
static int
-vmx_run(void *arg, int vcpu, register_t rip, struct vm_exit *vmexit)
+vmx_run(void *arg, int vcpu, register_t rip)
{
int error, vie, rc, handled, astpending;
uint32_t exit_reason;
struct vmx *vmx;
struct vmxctx *vmxctx;
struct vmcs *vmcs;
+ struct vm_exit *vmexit;
vmx = arg;
vmcs = &vmx->vmcs[vcpu];
vmxctx = &vmx->ctx[vcpu];
vmxctx->launched = 0;
+ vmexit = vm_exitinfo(vmx->vm, vcpu);
+
/*
* XXX Can we avoid doing this every time we do a vm run?
*/
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
index 62cc2a2..d896f6d 100644
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -72,6 +72,7 @@ struct vcpu {
int vcpuid;
struct savefpu *guestfpu; /* guest fpu state */
void *stats;
+ struct vm_exit exitinfo;
};
#define VCPU_F_PINNED 0x0001
#define VCPU_F_RUNNING 0x0002
@@ -110,8 +111,8 @@ static struct vmm_ops *ops;
#define VMM_CLEANUP() (ops != NULL ? (*ops->cleanup)() : 0)
#define VMINIT(vm) (ops != NULL ? (*ops->vminit)(vm): NULL)
-#define VMRUN(vmi, vcpu, rip, vmexit) \
- (ops != NULL ? (*ops->vmrun)(vmi, vcpu, rip, vmexit) : ENXIO)
+#define VMRUN(vmi, vcpu, rip) \
+ (ops != NULL ? (*ops->vmrun)(vmi, vcpu, rip) : ENXIO)
#define VMCLEANUP(vmi) (ops != NULL ? (*ops->vmcleanup)(vmi) : NULL)
#define VMMMAP(vmi, gpa, hpa, len, attr, prot, spm) \
(ops != NULL ? (*ops->vmmmap)(vmi, gpa, hpa, len, attr, prot, spm) : ENXIO)
@@ -164,6 +165,19 @@ vcpu_init(struct vm *vm, uint32_t vcpu_id)
vcpu->stats = vmm_stat_alloc();
}
+struct vm_exit *
+vm_exitinfo(struct vm *vm, int cpuid)
+{
+ struct vcpu *vcpu;
+
+ if (cpuid < 0 || cpuid >= VM_MAXCPU)
+ panic("vm_exitinfo: invalid cpuid %d", cpuid);
+
+ vcpu = &vm->vcpu[cpuid];
+
+ return (&vcpu->exitinfo);
+}
+
static int
vmm_init(void)
{
@@ -545,12 +559,15 @@ vm_run(struct vm *vm, struct vm_run *vmrun)
restore_guest_msrs(vm, vcpuid);
restore_guest_fpustate(vcpu);
- error = VMRUN(vm->cookie, vcpuid, vmrun->rip, &vmrun->vm_exit);
+ error = VMRUN(vm->cookie, vcpuid, vmrun->rip);
save_guest_fpustate(vcpu);
restore_host_msrs(vm, vcpuid);
vmm_stat_incr(vm, vcpuid, VCPU_TOTAL_RUNTIME, rdtsc() - tscval);
+ /* copy the exit information */
+ bcopy(&vcpu->exitinfo, &vmrun->vm_exit, sizeof(struct vm_exit));
+
critical_exit();
return (error);
OpenPOWER on IntegriCloud