From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jan Kiszka Subject: [PATCH 1/11] QEMU/KVM: Fix deadlocks in monitor and debugger Date: Tue, 27 May 2008 00:09:34 +0200 Message-ID: <483B351E.6010305@web.de> References: <4839B14A.3010406@web.de> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit Cc: Avi Kivity , Hollis Blanchard , Jerone Young , Joerg Roedel To: kvm-devel Return-path: Received: from fmmailgate01.web.de ([217.72.192.221]:50687 "EHLO fmmailgate01.web.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754889AbYEZWK4 (ORCPT ); Mon, 26 May 2008 18:10:56 -0400 In-Reply-To: <4839B14A.3010406@web.de> Sender: kvm-owner@vger.kernel.org List-ID: Some monitor commands as well as the vm_stop() issued by the gdbstub on external interruption so far deadlock on vcpu locks in the kernel. Patch below resolves the issue by temporarily or permanently stopping all vcpu threads before issuing the related KVM IOCTLs. It enables, e.g., to break into guest code spinning in the vcpu and to use things like "info cpus" in the monitor. Signed-off-by: Jan Kiszka --- qemu/qemu-kvm.c | 41 +++++++++++++++++++++++++++-------------- qemu/vl.c | 2 +- 2 files changed, 28 insertions(+), 15 deletions(-) Index: b/qemu/qemu-kvm.c =================================================================== --- a/qemu/qemu-kvm.c +++ b/qemu/qemu-kvm.c @@ -137,18 +137,6 @@ static int pre_kvm_run(void *opaque, int return 0; } -void kvm_load_registers(CPUState *env) -{ - if (kvm_enabled()) - kvm_arch_load_regs(env); -} - -void kvm_save_registers(CPUState *env) -{ - if (kvm_enabled()) - kvm_arch_save_regs(env); -} - int kvm_cpu_exec(CPUState *env) { int r; @@ -252,6 +240,26 @@ static void kvm_vm_state_change_handler( pause_all_threads(); } +void kvm_load_registers(CPUState *env) +{ + assert(!vm_running); + + if (kvm_enabled()) + kvm_arch_load_regs(env); +} + +void kvm_save_registers(CPUState *env) +{ + if (!kvm_enabled()) + return; + + if (vm_running) + pause_all_threads(); + kvm_arch_save_regs(env); + if (vm_running) + resume_all_threads(); +} + static void update_regs_for_sipi(CPUState *env) { kvm_arch_update_regs_for_sipi(env); @@ -740,7 +748,7 @@ int kvm_qemu_init_env(CPUState *cenv) int kvm_update_debugger(CPUState *env) { struct kvm_debug_guest dbg; - int i; + int i, r; memset(dbg.breakpoints, 0, sizeof(dbg.breakpoints)); @@ -753,7 +761,12 @@ int kvm_update_debugger(CPUState *env) } dbg.singlestep = env->singlestep_enabled; } - return kvm_guest_debug(kvm_context, env->cpu_index, &dbg); + if (vm_running) + pause_all_threads(); + r = kvm_guest_debug(kvm_context, env->cpu_index, &dbg); + if (vm_running) + resume_all_threads(); + return r; } Index: b/qemu/vl.c =================================================================== --- a/qemu/vl.c +++ b/qemu/vl.c @@ -7312,12 +7312,12 @@ void vm_stop(int reason) { if (vm_running) { cpu_disable_ticks(); - vm_running = 0; if (reason != 0) { if (vm_stop_cb) { vm_stop_cb(vm_stop_opaque, reason); } } + vm_running = 0; vm_state_notify(0); } }