summaryrefslogtreecommitdiffstats
path: root/sys/amd64/vmm/intel/vmx.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2014-07-21 02:39:17 +0000
committerjhb <jhb@FreeBSD.org>2014-07-21 02:39:17 +0000
commit888f6511e321556007cf471f691cb84d9a817237 (patch)
tree84ace0524c020288c47a07096fb6abcb1d3387d4 /sys/amd64/vmm/intel/vmx.c
parentd034cf40e56b09120dc35d432b7fdc536c54f6ec (diff)
downloadFreeBSD-src-888f6511e321556007cf471f691cb84d9a817237.zip
FreeBSD-src-888f6511e321556007cf471f691cb84d9a817237.tar.gz
MFC 263780,264516,265062,265101,265203,265364:
Add an ioctl to suspend a virtual machine (VM_SUSPEND). Add logic in the HLT exit handler to detect if the guest has put all vcpus to sleep permanently by executing a HLT with interrupts disabled. When this condition is detected the guest with be suspended with a reason of VM_SUSPEND_HALT and the bhyve(8) process will exit. This logic can be disabled via the tunable 'hw.vmm.halt_detection'.
Diffstat (limited to 'sys/amd64/vmm/intel/vmx.c')
-rw-r--r--sys/amd64/vmm/intel/vmx.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c
index 2da0ab7..1c39552 100644
--- a/sys/amd64/vmm/intel/vmx.c
+++ b/sys/amd64/vmm/intel/vmx.c
@@ -2136,7 +2136,7 @@ vmx_exit_handle_nmi(struct vmx *vmx, int vcpuid, struct vm_exit *vmexit)
static int
vmx_run(void *arg, int vcpu, register_t startrip, pmap_t pmap,
- void *rendezvous_cookie)
+ void *rendezvous_cookie, void *suspend_cookie)
{
int rc, handled, launched;
struct vmx *vmx;
@@ -2193,9 +2193,10 @@ vmx_run(void *arg, int vcpu, register_t startrip, pmap_t pmap,
* pmap_invalidate_ept().
*/
disable_intr();
- if (curthread->td_flags & (TDF_ASTPENDING | TDF_NEEDRESCHED)) {
+ if (vcpu_suspended(suspend_cookie)) {
enable_intr();
- handled = vmx_exit_astpending(vmx, vcpu, vmexit);
+ vm_exit_suspended(vmx->vm, vcpu, vmcs_guest_rip());
+ handled = UNHANDLED;
break;
}
@@ -2205,6 +2206,12 @@ vmx_run(void *arg, int vcpu, register_t startrip, pmap_t pmap,
break;
}
+ if (curthread->td_flags & (TDF_ASTPENDING | TDF_NEEDRESCHED)) {
+ enable_intr();
+ handled = vmx_exit_astpending(vmx, vcpu, vmexit);
+ break;
+ }
+
vmx_inject_interrupts(vmx, vcpu, vlapic);
vmx_run_trace(vmx, vcpu);
rc = vmx_enter_guest(vmxctx, vmx, launched);
OpenPOWER on IntegriCloud