aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2015-11-05 18:33:00 +0000
committerWill Deacon <will.deacon@arm.com>2015-11-05 18:35:13 +0000
commit2aa76b2616bcace1d668a879d834679dfa00dc8c (patch)
tree7a7829f06ee5830de2e8c202381438433b80d4d8 /include
parent3ce000c5f3a8341fe190883f43dd9bd6cf15a2e7 (diff)
downloadkvmtool-2aa76b2616bcace1d668a879d834679dfa00dc8c.tar.gz
kvmtool: fix VM exit race attempting to pthread_kill an exited thread
lkvm currently suffers from a Segmentation Fault when exiting, which can also lead to the console not being cleaned up correctly after a VM exits. The issue is that (the misnamed) kvm_cpu__reboot function sends a SIGKVMEXIT to each vcpu thread, which causes those vcpu threads to exit once their main loops (kvm_cpu__start) detect that cpu->is_running is now false. The lack of synchronisation in this exit path means that a concurrent pause event (due to the br_write_lock in ioport__unregister) ends up sending SIGKVMPAUSE to an exited thread, resulting in a SEGV. This patch fixes the issue by moving kvm_cpu__reboot into kvm.c (renaming it in the process) where it can hold the pause_lock mutex across the reboot operation. This in turn makes it safe for the pause code to check the is_running field of each CPU before attempting to send a SIGKVMPAUSE signal. Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'include')
-rw-r--r--include/kvm/kvm-cpu.h1
-rw-r--r--include/kvm/kvm.h1
2 files changed, 1 insertions, 1 deletions
diff --git a/include/kvm/kvm-cpu.h b/include/kvm/kvm-cpu.h
index aa0cb543..c4c9cca4 100644
--- a/include/kvm/kvm-cpu.h
+++ b/include/kvm/kvm-cpu.h
@@ -12,7 +12,6 @@ void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu);
void kvm_cpu__setup_cpuid(struct kvm_cpu *vcpu);
void kvm_cpu__enable_singlestep(struct kvm_cpu *vcpu);
void kvm_cpu__run(struct kvm_cpu *vcpu);
-void kvm_cpu__reboot(struct kvm *kvm);
int kvm_cpu__start(struct kvm_cpu *cpu);
bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu);
int kvm_cpu__get_endianness(struct kvm_cpu *vcpu);
diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
index 37155dbc..a474dae6 100644
--- a/include/kvm/kvm.h
+++ b/include/kvm/kvm.h
@@ -93,6 +93,7 @@ int kvm__register_mmio(struct kvm *kvm, u64 phys_addr, u64 phys_addr_len, bool c
void (*mmio_fn)(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len, u8 is_write, void *ptr),
void *ptr);
bool kvm__deregister_mmio(struct kvm *kvm, u64 phys_addr);
+void kvm__reboot(struct kvm *kvm);
void kvm__pause(struct kvm *kvm);
void kvm__continue(struct kvm *kvm);
void kvm__notify_paused(void);