aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeel Natu <neel@FreeBSD.org>2014-06-10 16:45:58 +0000
committerNeel Natu <neel@FreeBSD.org>2014-06-10 16:45:58 +0000
commit404874659fd4022929e587ef848879fa301b174d (patch)
tree1aaa46ce5242e690d93c0a09ce1322d7183e06b5
parent00db3c6309708401fb3391fbfa0e0916ae219cdf (diff)
downloadsrc-404874659fd4022929e587ef848879fa301b174d.tar.gz
src-404874659fd4022929e587ef848879fa301b174d.zip
Add helper functions to populate VM exit information for rendezvous and
astpending exits. This is to reduce code duplication between VT-x and SVM implementations.
Notes
Notes: svn path=/head/; revision=267330
-rw-r--r--sys/amd64/include/vmm.h2
-rw-r--r--sys/amd64/vmm/intel/vmx.c40
-rw-r--r--sys/amd64/vmm/vmm.c26
3 files changed, 36 insertions, 32 deletions
diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h
index 00e1d96afe7f..86f696d7c1a4 100644
--- a/sys/amd64/include/vmm.h
+++ b/sys/amd64/include/vmm.h
@@ -146,6 +146,8 @@ cpuset_t vm_active_cpus(struct vm *vm);
cpuset_t vm_suspended_cpus(struct vm *vm);
struct vm_exit *vm_exitinfo(struct vm *vm, int vcpuid);
void vm_exit_suspended(struct vm *vm, int vcpuid, uint64_t rip);
+void vm_exit_rendezvous(struct vm *vm, int vcpuid, uint64_t rip);
+void vm_exit_astpending(struct vm *vm, int vcpuid, uint64_t rip);
/*
* Rendezvous all vcpus specified in 'dest' and execute 'func(arg)'.
diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c
index 91e8274fbd5d..ec628546456a 100644
--- a/sys/amd64/vmm/intel/vmx.c
+++ b/sys/amd64/vmm/intel/vmx.c
@@ -2263,32 +2263,7 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit)
return (handled);
}
-static __inline int
-vmx_exit_astpending(struct vmx *vmx, int vcpu, struct vm_exit *vmexit)
-{
-
- vmexit->rip = vmcs_guest_rip();
- vmexit->inst_length = 0;
- vmexit->exitcode = VM_EXITCODE_BOGUS;
- vmx_astpending_trace(vmx, vcpu, vmexit->rip);
- vmm_stat_incr(vmx->vm, vcpu, VMEXIT_ASTPENDING, 1);
-
- return (HANDLED);
-}
-
-static __inline int
-vmx_exit_rendezvous(struct vmx *vmx, int vcpu, struct vm_exit *vmexit)
-{
-
- vmexit->rip = vmcs_guest_rip();
- vmexit->inst_length = 0;
- vmexit->exitcode = VM_EXITCODE_RENDEZVOUS;
- vmm_stat_incr(vmx->vm, vcpu, VMEXIT_RENDEZVOUS, 1);
-
- return (UNHANDLED);
-}
-
-static __inline int
+static __inline void
vmx_exit_inst_error(struct vmxctx *vmxctx, int rc, struct vm_exit *vmexit)
{
@@ -2312,8 +2287,6 @@ vmx_exit_inst_error(struct vmxctx *vmxctx, int rc, struct vm_exit *vmexit)
default:
panic("vm_exit_inst_error: vmx_enter_guest returned %d", rc);
}
-
- return (UNHANDLED);
}
/*
@@ -2386,6 +2359,8 @@ vmx_run(void *arg, int vcpu, register_t startrip, pmap_t pmap,
vmcs_write(VMCS_GUEST_RIP, startrip);
vmx_set_pcpu_defaults(vmx, vcpu, pmap);
do {
+ handled = UNHANDLED;
+
/*
* Interrupts are disabled from this point on until the
* guest starts executing. This is done for the following
@@ -2408,19 +2383,20 @@ vmx_run(void *arg, int vcpu, register_t startrip, pmap_t pmap,
if (vcpu_suspended(suspend_cookie)) {
enable_intr();
vm_exit_suspended(vmx->vm, vcpu, vmcs_guest_rip());
- handled = UNHANDLED;
break;
}
if (vcpu_rendezvous_pending(rendezvous_cookie)) {
enable_intr();
- handled = vmx_exit_rendezvous(vmx, vcpu, vmexit);
+ vm_exit_rendezvous(vmx->vm, vcpu, vmcs_guest_rip());
break;
}
if (curthread->td_flags & (TDF_ASTPENDING | TDF_NEEDRESCHED)) {
enable_intr();
- handled = vmx_exit_astpending(vmx, vcpu, vmexit);
+ vm_exit_astpending(vmx->vm, vcpu, vmcs_guest_rip());
+ vmx_astpending_trace(vmx, vcpu, vmexit->rip);
+ handled = HANDLED;
break;
}
@@ -2440,7 +2416,7 @@ vmx_run(void *arg, int vcpu, register_t startrip, pmap_t pmap,
handled = vmx_exit_process(vmx, vcpu, vmexit);
} else {
enable_intr();
- handled = vmx_exit_inst_error(vmxctx, rc, vmexit);
+ vmx_exit_inst_error(vmxctx, rc, vmexit);
}
launched = 1;
vmx_exit_trace(vmx, vcpu, rip, exit_reason, handled);
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
index 435ba391e141..8edb3fb47917 100644
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -1331,6 +1331,32 @@ vm_exit_suspended(struct vm *vm, int vcpuid, uint64_t rip)
vmexit->u.suspended.how = vm->suspend;
}
+void
+vm_exit_rendezvous(struct vm *vm, int vcpuid, uint64_t rip)
+{
+ struct vm_exit *vmexit;
+
+ KASSERT(vm->rendezvous_func != NULL, ("rendezvous not in progress"));
+
+ vmexit = vm_exitinfo(vm, vcpuid);
+ vmexit->rip = rip;
+ vmexit->inst_length = 0;
+ vmexit->exitcode = VM_EXITCODE_RENDEZVOUS;
+ vmm_stat_incr(vm, vcpuid, VMEXIT_RENDEZVOUS, 1);
+}
+
+void
+vm_exit_astpending(struct vm *vm, int vcpuid, uint64_t rip)
+{
+ struct vm_exit *vmexit;
+
+ vmexit = vm_exitinfo(vm, vcpuid);
+ vmexit->rip = rip;
+ vmexit->inst_length = 0;
+ vmexit->exitcode = VM_EXITCODE_BOGUS;
+ vmm_stat_incr(vm, vcpuid, VMEXIT_ASTPENDING, 1);
+}
+
int
vm_run(struct vm *vm, struct vm_run *vmrun)
{