Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 26 Jul 2014 02:53:51 +0000 (UTC)
From:      Neel Natu <neel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r269109 - in head/sys/amd64: include vmm vmm/intel
Message-ID:  <201407260253.s6Q2rp8B032416@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201407260253.s6Q2rp8B032416>