diff mbox

[4/5] Fix a race during exit processing

Message ID 1459423707-8956-5-git-send-email-bsingharora@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Education Directorate March 31, 2016, 11:28 a.m. UTC
Fix a race, described below

	lkvm stop ...	handle_stop
			kvm_cpu__reboot
			kvm_cmd_run_exit
			vcpus exit
			...
			dev_exit
			...
			ioport__unregister
			..serial...
			kvm__pause --> br_write_lock
			pthread_kill

But the thread is already dead above.

We mark the cpus as dying so that kvm_pause does nothing.
This should not break any semantics

Signed-off-by: Balbir Singh <bsingharora@gmail.com>
---
 builtin-run.c | 3 +++
 kvm.c         | 5 +++++
 2 files changed, 8 insertions(+)

Comments

Will Deacon April 11, 2016, 3:37 p.m. UTC | #1
On Thu, Mar 31, 2016 at 10:28:26PM +1100, Balbir Singh wrote:
> Fix a race, described below
> 
> 	lkvm stop ...	handle_stop
> 			kvm_cpu__reboot
> 			kvm_cmd_run_exit
> 			vcpus exit
> 			...
> 			dev_exit
> 			...
> 			ioport__unregister
> 			..serial...
> 			kvm__pause --> br_write_lock
> 			pthread_kill
> 
> But the thread is already dead above.
> 
> We mark the cpus as dying so that kvm_pause does nothing.
> This should not break any semantics

I'm not convinced that this solves the whole problem. The fact of the
matter is that we're tearing down the VM whilst there may still be active
vcpus, so I'd much rather delay the teardown until we know that the vcpus
are all dead.

Patch incoming.

Will
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/builtin-run.c b/builtin-run.c
index 17b1428..cdc7158 100644
--- a/builtin-run.c
+++ b/builtin-run.c
@@ -58,6 +58,7 @@  __thread struct kvm_cpu *current_kvm_cpu;
 static int  kvm_run_wrapper;
 
 bool do_debug_print = false;
+int kvm_cmd_exit;
 
 static const char * const run_usage[] = {
 	"lkvm run [<options>] [<kernel image>]",
@@ -648,6 +649,7 @@  static void kvm_cmd_run_exit(struct kvm *kvm, int guest_ret)
 {
 	compat__print_all_messages();
 
+	kvm_cmd_exit = 1;
 	init_list__exit(kvm);
 
 	if (guest_ret == 0 && do_debug_print)
@@ -659,6 +661,7 @@  int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 	int ret = -EFAULT;
 	struct kvm *kvm;
 
+	kvm_cmd_exit = 0;
 	kvm = kvm_cmd_run_init(argc, argv);
 	if (IS_ERR(kvm))
 		return PTR_ERR(kvm);
diff --git a/kvm.c b/kvm.c
index 1081072..53cf0e2 100644
--- a/kvm.c
+++ b/kvm.c
@@ -33,6 +33,8 @@ 
 
 #define DEFINE_KVM_EXIT_REASON(reason) [reason] = #reason
 
+extern int kvm_cmd_exit;
+
 const char *kvm_exit_reasons[] = {
 	DEFINE_KVM_EXIT_REASON(KVM_EXIT_UNKNOWN),
 	DEFINE_KVM_EXIT_REASON(KVM_EXIT_EXCEPTION),
@@ -435,6 +437,9 @@  void kvm__pause(struct kvm *kvm)
 	if (!kvm->cpus[0] || kvm->cpus[0]->thread == 0)
 		return;
 
+	if (kvm_cmd_exit)
+		return;
+
 	mutex_lock(&pause_lock);
 
 	pause_event = eventfd(0, 0);