When shutting down SMP guests only VCPU #0 will receive a KVM_EXIT_SHUTDOWN. Waiting for all VCPU threads to exit causes them to hang. Instead, notify all VCPU threads once VCPU #0 thread is terminated so they could also stop properly. Signed-off-by: Sasha Levin <levinsasha928@xxxxxxxxx> --- tools/kvm/include/kvm/kvm.h | 2 ++ tools/kvm/kvm-cpu.c | 13 ++++++++++++- tools/kvm/kvm-run.c | 10 +++++++--- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h index d9943bf..aafba87 100644 --- a/tools/kvm/include/kvm/kvm.h +++ b/tools/kvm/include/kvm/kvm.h @@ -11,6 +11,8 @@ #define KVM_32BIT_GAP_SIZE (512 << 20) #define KVM_32BIT_GAP_START ((1ULL << 32) - KVM_32BIT_GAP_SIZE) +#define SIGKVMEXIT (SIGUSR1 + 2) + struct kvm { int sys_fd; /* For system ioctls(), i.e. /dev/kvm */ int vm_fd; /* For VM ioctls() */ diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c index cdfeb85..331e025 100644 --- a/tools/kvm/kvm-cpu.c +++ b/tools/kvm/kvm-cpu.c @@ -379,6 +379,11 @@ void kvm_cpu__run(struct kvm_cpu *vcpu) die_perror("KVM_RUN failed"); } +static void kvm_cpu_exit_handler(int signum) +{ + /* Don't do anything here */ +} + int kvm_cpu__start(struct kvm_cpu *cpu) { sigset_t sigset; @@ -388,6 +393,8 @@ int kvm_cpu__start(struct kvm_cpu *cpu) pthread_sigmask(SIG_BLOCK, &sigset, NULL); + signal(SIGKVMEXIT, kvm_cpu_exit_handler); + kvm_cpu__setup_cpuid(cpu); kvm_cpu__reset_vcpu(cpu); @@ -430,7 +437,11 @@ int kvm_cpu__start(struct kvm_cpu *cpu) break; } case KVM_EXIT_INTR: - break; + /* + * Currently we only handle exit signal, which means + * we just exit if KVM_RUN exited due to a signal. + */ + goto exit_kvm; case KVM_EXIT_SHUTDOWN: goto exit_kvm; default: diff --git a/tools/kvm/kvm-run.c b/tools/kvm/kvm-run.c index 63181bf..8379a52 100644 --- a/tools/kvm/kvm-run.c +++ b/tools/kvm/kvm-run.c @@ -404,6 +404,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix) int max_cpus; char *hi; int i; + void *ret; signal(SIGALRM, handle_sigalrm); signal(SIGQUIT, handle_sigquit); @@ -583,14 +584,17 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix) die("unable to create KVM VCPU thread"); } - for (i = 0; i < nrcpus; i++) { - void *ret; + /* Only VCPU #0 is going to exit by itself when shutting down */ + if (pthread_join(kvm_cpus[0]->thread, &ret) != 0) + exit_code = 1; + for (i = 1; i < nrcpus; i++) { + pthread_kill(kvm_cpus[i]->thread, SIGKVMEXIT); if (pthread_join(kvm_cpus[i]->thread, &ret) != 0) die("pthread_join"); if (ret != NULL) - exit_code = 1; + exit_code = 1; } kvm__delete(kvm); -- 1.7.5.rc3 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html