All of lore.kernel.org
 help / color / mirror / Atom feed
From: Avi Kivity <avi@redhat.com>
To: linux-kernel@vger.kernel.org
Cc: kvm@vger.kernel.org
Subject: [PATCH 43/43] KVM: Fix interrupt unhalting a vcpu when it shouldn't
Date: Mon, 18 May 2009 12:23:05 +0300	[thread overview]
Message-ID: <1242638585-18470-44-git-send-email-avi@redhat.com> (raw)
In-Reply-To: <1242638585-18470-1-git-send-email-avi@redhat.com>

From: Gleb Natapov <gleb@redhat.com>

kvm_vcpu_block() unhalts vpu on an interrupt/timer without checking
if interrupt window is actually opened.

Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/ia64/kvm/kvm-ia64.c        |    6 ++++++
 arch/powerpc/kvm/powerpc.c      |    6 ++++++
 arch/s390/kvm/interrupt.c       |    6 ++++++
 arch/x86/include/asm/kvm_host.h |    2 +-
 arch/x86/kvm/svm.c              |   10 ++++++++++
 arch/x86/kvm/vmx.c              |    8 +++++++-
 arch/x86/kvm/x86.c              |    5 +++++
 include/linux/kvm_host.h        |    1 +
 virt/kvm/kvm_main.c             |    3 ++-
 9 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index d2a90fd..3bf0a34 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -1963,6 +1963,12 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu)
 	return 0;
 }
 
+int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
+{
+	/* do real check here */
+	return 1;
+}
+
 int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
 {
 	return vcpu->arch.timer_fired;
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 9057335..2cf915e 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -41,6 +41,12 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
 	return !!(v->arch.pending_exceptions);
 }
 
+int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
+{
+	/* do real check here */
+	return 1;
+}
+
 int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
 {
 	return !(v->arch.msr & MSR_WE);
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 0189356..4ed4c3a 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -318,6 +318,12 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu)
 	return rc;
 }
 
+int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
+{
+	/* do real check here */
+	return 1;
+}
+
 int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
 {
 	return 0;
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 4627627..8351c4d 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -521,7 +521,7 @@ struct kvm_x86_ops {
 	void (*inject_pending_irq)(struct kvm_vcpu *vcpu);
 	void (*inject_pending_vectors)(struct kvm_vcpu *vcpu,
 				       struct kvm_run *run);
-
+	int (*interrupt_allowed)(struct kvm_vcpu *vcpu);
 	int (*set_tss_addr)(struct kvm *kvm, unsigned int addr);
 	int (*get_tdp_level)(void);
 	int (*get_mt_mask_shift)(void);
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index aa528db..de74104 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -2270,6 +2270,15 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu)
 		vmcb->control.intercept_cr_write |= INTERCEPT_CR8_MASK;
 }
 
+static int svm_interrupt_allowed(struct kvm_vcpu *vcpu)
+{
+	struct vcpu_svm *svm = to_svm(vcpu);
+	struct vmcb *vmcb = svm->vmcb;
+	return (vmcb->save.rflags & X86_EFLAGS_IF) &&
+		!(vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) &&
+		(svm->vcpu.arch.hflags & HF_GIF_MASK);
+}
+
 static void svm_intr_assist(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
@@ -2649,6 +2658,7 @@ static struct kvm_x86_ops svm_x86_ops = {
 	.exception_injected = svm_exception_injected,
 	.inject_pending_irq = svm_intr_assist,
 	.inject_pending_vectors = do_interrupt_requests,
+	.interrupt_allowed = svm_interrupt_allowed,
 
 	.set_tss_addr = svm_set_tss_addr,
 	.get_tdp_level = get_npt_level,
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index da6461d..b9e06b0 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2490,6 +2490,12 @@ static void vmx_update_window_states(struct kvm_vcpu *vcpu)
 				 GUEST_INTR_STATE_MOV_SS)));
 }
 
+static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu)
+{
+	vmx_update_window_states(vcpu);
+	return vcpu->arch.interrupt_window_open;
+}
+
 static void do_interrupt_requests(struct kvm_vcpu *vcpu,
 				       struct kvm_run *kvm_run)
 {
@@ -3691,7 +3697,7 @@ static struct kvm_x86_ops vmx_x86_ops = {
 	.exception_injected = vmx_exception_injected,
 	.inject_pending_irq = vmx_intr_assist,
 	.inject_pending_vectors = do_interrupt_requests,
-
+	.interrupt_allowed = vmx_interrupt_allowed,
 	.set_tss_addr = vmx_set_tss_addr,
 	.get_tdp_level = get_ept_level,
 	.get_mt_mask_shift = vmx_get_mt_mask_shift,
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index aa8b585..ab61ea6 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4471,3 +4471,8 @@ void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
 		smp_call_function_single(ipi_pcpu, vcpu_kick_intr, vcpu, 0);
 	put_cpu();
 }
+
+int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
+{
+	return kvm_x86_ops->interrupt_allowed(vcpu);
+}
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 40e49ed..72d5684 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -298,6 +298,7 @@ int kvm_arch_hardware_setup(void);
 void kvm_arch_hardware_unsetup(void);
 void kvm_arch_check_processor_compat(void *rtn);
 int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu);
+int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu);
 
 void kvm_free_physmem(struct kvm *kvm);
 
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index ffe2826..3265566 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1610,7 +1610,8 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)
 	for (;;) {
 		prepare_to_wait(&vcpu->wq, &wait, TASK_INTERRUPTIBLE);
 
-		if (kvm_cpu_has_interrupt(vcpu) ||
+		if ((kvm_arch_interrupt_allowed(vcpu) &&
+					kvm_cpu_has_interrupt(vcpu)) ||
 				kvm_arch_vcpu_runnable(vcpu)) {
 			set_bit(KVM_REQ_UNHALT, &vcpu->requests);
 			break;
-- 
1.6.0.6


      parent reply	other threads:[~2009-05-18  9:38 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-05-18  9:22 [PATCH 00/43] KVM updates for the 2.6.31 merge window (batch 1/4) Avi Kivity
2009-05-18  9:22 ` [PATCH 01/43] KVM: VMX: Don't use highmem pages for the msr and pio bitmaps Avi Kivity
2009-05-18  9:22 ` [PATCH 02/43] KVM: VMX: Don't intercept MSR_KERNEL_GS_BASE Avi Kivity
2009-05-18  9:22 ` [PATCH 03/43] KVM: Split IOAPIC structure Avi Kivity
2009-05-18  9:22 ` [PATCH 04/43] KVM: Unify the delivery of IOAPIC and MSI interrupts Avi Kivity
2009-05-18  9:22 ` [PATCH 05/43] KVM: Change API of kvm_ioapic_get_delivery_bitmask Avi Kivity
2009-05-18  9:22 ` [PATCH 06/43] KVM: Update intr delivery func to accept unsigned long* bitmap Avi Kivity
2009-05-18  9:22 ` [PATCH 07/43] KVM: bit ops for deliver_bitmap Avi Kivity
2009-05-18  9:22 ` [PATCH 08/43] KVM: Ioctls for init MSI-X entry Avi Kivity
2009-05-18  9:22 ` [PATCH 09/43] KVM: Add MSI-X interrupt injection logic Avi Kivity
2009-05-18  9:22 ` [PATCH 10/43] KVM: Enable MSI-X for KVM assigned device Avi Kivity
2009-05-18  9:22 ` [PATCH 11/43] KVM: x86: silence preempt warning on kvm_write_guest_time Avi Kivity
2009-05-18  9:22 ` [PATCH 12/43] KVM: x86: paravirt skip pit-through-ioapic boot check Avi Kivity
2009-05-18  9:22 ` [PATCH 13/43] KVM: declare ioapic functions only on affected hardware Avi Kivity
2009-05-18  9:22 ` [PATCH 14/43] KVM: PIT: remove unused scheduled variable Avi Kivity
2009-05-18  9:22 ` [PATCH 15/43] KVM: PIT: remove usage of count_load_time for channel 0 Avi Kivity
2009-05-18  9:22 ` [PATCH 16/43] KVM: unify part of generic timer handling Avi Kivity
2009-05-18  9:22 ` [PATCH 17/43] KVM: ia64: fix compilation error in kvm_get_lowest_prio_vcpu Avi Kivity
2009-05-18  9:22 ` [PATCH 18/43] KVM: Merge kvm_ioapic_get_delivery_bitmask into kvm_get_intr_delivery_bitmask Avi Kivity
2009-05-18  9:22 ` [PATCH 19/43] KVM: MMU: remove call to kvm_mmu_pte_write from walk_addr Avi Kivity
2009-05-18  9:22 ` [PATCH 20/43] KVM: APIC: kvm_apic_set_irq deliver all kinds of interrupts Avi Kivity
2009-05-18  9:22 ` [PATCH 21/43] KVM: ioapic/msi interrupt delivery consolidation Avi Kivity
2009-05-18  9:22 ` [PATCH 22/43] KVM: consolidate ioapic/ipi interrupt delivery logic Avi Kivity
2009-05-18  9:22 ` [PATCH 23/43] KVM: change the way how lowest priority vcpu is calculated Avi Kivity
2009-05-18  9:22 ` [PATCH 24/43] KVM: APIC: get rid of deliver_bitmask Avi Kivity
2009-05-18  9:22 ` [PATCH 25/43] KVM: ia64: Map in SN2 RTC registers to the VMM module Avi Kivity
2009-05-18  9:22 ` [PATCH 26/43] KVM: ia64: Create inline function kvm_get_itc() to centralize ITC reading Avi Kivity
2009-05-18  9:22 ` [PATCH 27/43] KVM: ia64: SN2 adjust emulated ITC frequency to match RTC frequency Avi Kivity
2009-05-18  9:22 ` [PATCH 28/43] KVM: ia64: Drop in SN2 replacement of fast path ITC emulation fault handler Avi Kivity
2009-05-18  9:22 ` [PATCH 29/43] KVM: make 'lapic_timer_ops' and 'kpit_ops' static Avi Kivity
2009-05-18  9:22 ` [PATCH 30/43] KVM: Device assignment framework rework Avi Kivity
2009-05-18  9:22 ` [PATCH 31/43] KVM: MMU: do not free active mmu pages in free_mmu_pages() Avi Kivity
2009-05-18  9:22 ` [PATCH 32/43] KVM: x86: Ignore reads to EVNTSEL MSRs Avi Kivity
2009-05-18  9:22 ` [PATCH 33/43] KVM: SVM: Remove duplicate code in svm_do_inject_vector() Avi Kivity
2009-05-18  9:22 ` [PATCH 34/43] KVM: reuse (pop|push)_irq from svm.c in vmx.c Avi Kivity
2009-05-18  9:22 ` [PATCH 35/43] KVM: VMX: Make module parameters readable Avi Kivity
2009-05-18  9:22 ` [PATCH 36/43] KVM: VMX: Rename kvm_handle_exit() to vmx_handle_exit() Avi Kivity
2009-05-18  9:22 ` [PATCH 37/43] KVM: VMX: Simplify module parameter names Avi Kivity
2009-05-18  9:23 ` [PATCH 38/43] KVM: VMX: Annotate module parameters as __read_mostly Avi Kivity
2009-05-18  9:23 ` [PATCH 39/43] KVM: VMX: Zero the vpid module parameter if vpid is not supported Avi Kivity
2009-05-18  9:23 ` [PATCH 40/43] KVM: VMX: Zero ept module parameter if ept is not present Avi Kivity
2009-05-18  9:23 ` [PATCH 41/43] KVM: VMX: Fold vm_need_ept() into callers Avi Kivity
2009-05-18  9:23 ` [PATCH 42/43] KVM: Timer event should not unconditionally unhalt vcpu Avi Kivity
2009-05-18  9:23 ` Avi Kivity [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1242638585-18470-44-git-send-email-avi@redhat.com \
    --to=avi@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.