diff options
author | jhb <jhb@FreeBSD.org> | 2014-07-21 02:39:17 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2014-07-21 02:39:17 +0000 |
commit | 888f6511e321556007cf471f691cb84d9a817237 (patch) | |
tree | 84ace0524c020288c47a07096fb6abcb1d3387d4 /sys/amd64/vmm/intel/vmx.c | |
parent | d034cf40e56b09120dc35d432b7fdc536c54f6ec (diff) | |
download | FreeBSD-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.c | 13 |
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); |