Author: neel
Date: Sat Jul 26 02:53:51 2014
New Revision: 269109
URL: http://svnweb.freebsd.org/changeset/base/269109

Log:
  If a vcpu has issued a HLT instruction with interrupts disabled then it sleeps
  forever in vm_handle_hlt().
  
  This is usually not an issue as long as one of the other vcpus properly resets
  or powers off the virtual machine. However, if the bhyve(8) process is killed
  with a signal the halted vcpu cannot be woken up because it's sleep cannot be
  interrupted.
  
  Fix this by waking up periodically and returning from vm_handle_hlt() if
  TDF_ASTPENDING is set.
  
  Reported by:  Leon Dang
  Sponsored by: Nahanni Systems

Modified:
  head/sys/amd64/include/vmm.h
  head/sys/amd64/vmm/intel/vmx.c
  head/sys/amd64/vmm/vmm.c

Modified: head/sys/amd64/include/vmm.h
==============================================================================
--- head/sys/amd64/include/vmm.h        Sat Jul 26 02:51:46 2014        
(r269108)
+++ head/sys/amd64/include/vmm.h        Sat Jul 26 02:53:51 2014        
(r269109)
@@ -270,6 +270,14 @@ vcpu_is_running(struct vm *vm, int vcpu,
        return (vcpu_get_state(vm, vcpu, hostcpu) == VCPU_RUNNING);
 }
 
+#ifdef _SYS_PROC_H_
+static int __inline
+vcpu_should_yield(struct vm *vm, int vcpu)
+{
+       return (curthread->td_flags & (TDF_ASTPENDING | TDF_NEEDRESCHED));
+}
+#endif
+
 void *vcpu_stats(struct vm *vm, int vcpu);
 void vcpu_notify_event(struct vm *vm, int vcpuid, bool lapic_intr);
 struct vmspace *vm_get_vmspace(struct vm *vm);

Modified: head/sys/amd64/vmm/intel/vmx.c
==============================================================================
--- head/sys/amd64/vmm/intel/vmx.c      Sat Jul 26 02:51:46 2014        
(r269108)
+++ head/sys/amd64/vmm/intel/vmx.c      Sat Jul 26 02:53:51 2014        
(r269109)
@@ -2559,7 +2559,7 @@ vmx_run(void *arg, int vcpu, register_t 
                        break;
                }
 
-               if (curthread->td_flags & (TDF_ASTPENDING | TDF_NEEDRESCHED)) {
+               if (vcpu_should_yield(vm, vcpu)) {
                        enable_intr();
                        vm_exit_astpending(vmx->vm, vcpu, vmcs_guest_rip());
                        vmx_astpending_trace(vmx, vcpu, vmexit->rip);

Modified: head/sys/amd64/vmm/vmm.c
==============================================================================
--- head/sys/amd64/vmm/vmm.c    Sat Jul 26 02:51:46 2014        (r269108)
+++ head/sys/amd64/vmm/vmm.c    Sat Jul 26 02:53:51 2014        (r269109)
@@ -1105,6 +1105,10 @@ vm_handle_hlt(struct vm *vm, int vcpuid,
                        }
                }
 
+               /* Don't go to sleep if the vcpu thread needs to yield */
+               if (vcpu_should_yield(vm, vcpuid))
+                       break;
+
                /*
                 * Some Linux guests implement "halt" by having all vcpus
                 * execute HLT with interrupts disabled. 'halted_cpus' keeps
@@ -1128,7 +1132,11 @@ vm_handle_hlt(struct vm *vm, int vcpuid,
 
                t = ticks;
                vcpu_require_state_locked(vcpu, VCPU_SLEEPING);
-               msleep_spin(vcpu, &vcpu->mtx, wmesg, 0);
+               /*
+                * XXX msleep_spin() cannot be interrupted by signals so
+                * wake up periodically to check pending signals.
+                */
+               msleep_spin(vcpu, &vcpu->mtx, wmesg, hz);
                vcpu_require_state_locked(vcpu, VCPU_FROZEN);
                vmm_stat_incr(vm, vcpuid, VCPU_IDLE_TICKS, ticks - t);
        }
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to