From mboxrd@z Thu Jan 1 00:00:00 1970 From: Marcelo Tosatti Subject: KVM: x86: do not execute guest code if vcpu not runnable Date: Sat, 19 Jul 2008 15:11:44 -0300 Message-ID: <20080719181143.GA27283@dmt.cnet> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: kvm-devel To: Avi Kivity Return-path: Received: from mx1.redhat.com ([66.187.233.31]:43231 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755009AbYGSSMO (ORCPT ); Sat, 19 Jul 2008 14:12:14 -0400 Content-Disposition: inline Sender: kvm-owner@vger.kernel.org List-ID: If a vcpu has been offlined, or not initialized at all, signals requesting userspace work to be performed will result in KVM attempting to re-entry guest mode. Problem is that the in-kernel irqchip emulation happily executes HALTED state vcpu's. This breaks "savevm" on Windows SMP installation, for example. Also, setting the mpstate to runnable when setting an IRQ via pic_irq_request / kvm_apic_set_irq is necessary due to this check on emulate_halt: kvm_vcpu_block(vcpu); down_read(&vcpu->kvm->slots_lock); if (vcpu->arch.mp_state != KVM_MP_STATE_RUNNABLE) return -EINTR; Otherwise the vcpu will return to userspace needlessly. Signed-off-by: Marcelo Tosatti diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c index c31164e..44075fa 100644 --- a/arch/x86/kvm/i8259.c +++ b/arch/x86/kvm/i8259.c @@ -424,8 +424,10 @@ static void pic_irq_request(void *opaque, int level) struct kvm_vcpu *vcpu = kvm->vcpus[0]; pic_irqchip(kvm)->output = level; - if (vcpu) + if (vcpu) { + vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; kvm_vcpu_kick(vcpu); + } } struct kvm_pic *kvm_create_pic(struct kvm *kvm) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 9fde0ac..d81976c 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -195,6 +195,7 @@ int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 trig) apic_set_vector(vec, apic->regs + APIC_TMR); else apic_clear_vector(vec, apic->regs + APIC_TMR); + vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; kvm_vcpu_kick(apic->vcpu); return 1; } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 07d7ca9..7befd6c 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2976,10 +2976,12 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) if (vcpu->sigset_active) sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); - if (unlikely(vcpu->arch.mp_state == KVM_MP_STATE_UNINITIALIZED)) { + if (unlikely(!kvm_arch_vcpu_runnable(vcpu))) { kvm_vcpu_block(vcpu); - r = -EAGAIN; - goto out; + if (!kvm_arch_vcpu_runnable(vcpu)) { + r = -EAGAIN; + goto out; + } } /* re-sync apic's tpr */