From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Yang, Sheng" Subject: [PATCH] KVM: Fix QEmu interrupted HLT emulation Date: Thu, 31 Jul 2008 13:52:10 +0800 Message-ID: <200807311352.10657.sheng.yang@intel.com> References: <200807302155.19732.sheng.yang@intel.com> <200807311247.21350.sheng.yang@intel.com> Mime-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_KMVkImEP2Mcyob+" Cc: Avi Kivity To: kvm@vger.kernel.org Return-path: Received: from mga02.intel.com ([134.134.136.20]:32702 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751355AbYGaFuB (ORCPT ); Thu, 31 Jul 2008 01:50:01 -0400 In-Reply-To: <200807311247.21350.sheng.yang@intel.com> Sender: kvm-owner@vger.kernel.org List-ID: --Boundary-00=_KMVkImEP2Mcyob+ Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Content-Disposition: inline From: Sheng Yang Date: Thu, 31 Jul 2008 13:43:58 +0800 Subject: [PATCH] KVM: Fix QEmu interrupted HLT emulation QEmu can interrupt VCPU from HLT emulation without setting mp_state to MP_STATE_RUNNABLE, when it kick vcpus which are doing HLT emulation to do something like "stop" or "info cpus". Here are two issues of this behaviour: First, if vcpu exit to QEmu with MP_STATE_HALTED, it would keep in this state later for vcpu_run(), which is eerie... Second, a practical problem: bios load AP boot up code to 0x10000 (now), and AP is running HLT there. But later grub load it's stage2 code to the same address. Then if the halting vcpu was forced exit to QEmu in grub, and come back for vcpu_run later, it can't execute HLT instruction anymore, just because the bios code is not there, and it would follow a piece of code of grub, which would cause completely chaos... The second issue directly lead to guest crash or SMP linux can't boot up AP later if we "stop" or "info cpus" in grub. Though I also sent a patch for BIOS, it's necessary to get correct behavior here. The patch resumes the HLT emulation after interrupt by QEmu to fix it. Signed-off-by: Sheng Yang --- arch/x86/kvm/x86.c | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 94a2165..8219074 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2881,6 +2881,19 @@ again: clear_bit(KVM_REQ_PENDING_TIMER, &vcpu->requests); kvm_inject_pending_timer_irqs(vcpu); + /* + * If HLT emulating was interrupted by QEmu, we'd better resume it. + * And if QEmu don't interrupt it again, set correct state rather than + * keeping running with STATE_HALTED + */ + if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED) { + r = kvm_emulate_halt(vcpu); + if (!signal_pending(current) && + !kvm_arch_vcpu_runnable(vcpu)) + vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; + goto next_round; + } + preempt_disable(); kvm_x86_ops->prepare_guest_switch(vcpu); @@ -2962,6 +2975,7 @@ again: r = kvm_x86_ops->handle_exit(kvm_run, vcpu); +next_round: if (r > 0) { if (dm_request_for_irq_injection(vcpu, kvm_run)) { r = -EINTR; -- 1.5.4.5 --Boundary-00=_KMVkImEP2Mcyob+ Content-Type: text/x-diff; charset="utf-8"; name="0001-KVM-Fix-QEmu-interrupted-HLT-emulation.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0001-KVM-Fix-QEmu-interrupted-HLT-emulation.patch" =46rom ea0a1f70d44590929c9d618ee4bef8af1553b442 Mon Sep 17 00:00:00 2001 =46rom: Sheng Yang Date: Thu, 31 Jul 2008 13:43:58 +0800 Subject: [PATCH] KVM: Fix QEmu interrupted HLT emulation QEmu can interrupt VCPU from HLT emulation without setting mp_state to MP_STATE_RUNNABLE, when it kick vcpus which are doing HLT emulation to do something like "stop" or "info cpus". Here are two issues of this behaviour: =46irst, if vcpu exit to QEmu with MP_STATE_HALTED, it would keep in this s= tate later for vcpu_run(), which is eerie... Second, a practical problem: bios load AP boot up code to 0x10000 (now), an= d AP is running HLT there. But later grub load it's stage2 code to the same address= =2E Then if the halting vcpu was forced exit to QEmu in grub, and come back for vcpu= _run later, it can't execute HLT instruction anymore, just because the bios code is not= there, and it would follow a piece of code of grub, which would cause completely c= haos... The second issue directly lead to guest crash or SMP linux can't boot up AP later if we "stop" or "info cpus" in grub. Though I also sent a patch for B= IOS, it's necessary to get correct behavior here. The patch resumes the HLT emulation after interrupt by QEmu to fix it. Signed-off-by: Sheng Yang =2D-- arch/x86/kvm/x86.c | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 94a2165..8219074 100644 =2D-- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2881,6 +2881,19 @@ again: clear_bit(KVM_REQ_PENDING_TIMER, &vcpu->requests); kvm_inject_pending_timer_irqs(vcpu); =20 + /* + * If HLT emulating was interrupted by QEmu, we'd better resume it. + * And if QEmu don't interrupt it again, set correct state rather than + * keeping running with STATE_HALTED + */ + if (vcpu->arch.mp_state =3D=3D KVM_MP_STATE_HALTED) { + r =3D kvm_emulate_halt(vcpu); + if (!signal_pending(current) && + !kvm_arch_vcpu_runnable(vcpu)) + vcpu->arch.mp_state =3D KVM_MP_STATE_RUNNABLE; + goto next_round; + } + preempt_disable(); =20 kvm_x86_ops->prepare_guest_switch(vcpu); @@ -2962,6 +2975,7 @@ again: =20 r =3D kvm_x86_ops->handle_exit(kvm_run, vcpu); =20 +next_round: if (r > 0) { if (dm_request_for_irq_injection(vcpu, kvm_run)) { r =3D -EINTR; =2D-=20 1.5.4.5 --Boundary-00=_KMVkImEP2Mcyob+--