All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gleb Natapov <gleb@redhat.com>
To: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Alex Williamson <alex.williamson@redhat.com>,
	avi@redhat.com, kvm@vger.kernel.org,
	linux-kernel@vger.kernel.org, jan.kiszka@siemens.com
Subject: Re: [PATCH v5 3/4] kvm: Create kvm_clear_irq()
Date: Wed, 18 Jul 2012 09:27:42 +0300	[thread overview]
Message-ID: <20120718062742.GH6479@redhat.com> (raw)
In-Reply-To: <20120717161452.GA12114@redhat.com>

On Tue, Jul 17, 2012 at 07:14:52PM +0300, Michael S. Tsirkin wrote:
> > _Seems_ racy, or _is_ racy?  Please identify the race.
> 
> Look at this:
> 
> static inline int kvm_irq_line_state(unsigned long *irq_state,
>                                      int irq_source_id, int level)
> {
>         /* Logical OR for level trig interrupt */
>         if (level)
>                 set_bit(irq_source_id, irq_state);
>         else
>                 clear_bit(irq_source_id, irq_state);
> 
>         return !!(*irq_state);
> }
> 
> 
> Now:
> If other CPU changes some other bit after the atomic change,
> it looks like !!(*irq_state) might return a stale value.
> 
> CPU 0 clears bit 0. CPU 1 sets bit 1. CPU 1 sets level to 1.
> If CPU 0 sees a stale value now it will return 0 here
> and interrupt will get cleared.
> 
This will hardly happen on x86 especially since bit is set with
serialized instruction. But there is actually a race here.
CPU 0 clears bit 0. CPU 0 read irq_state as 0. CPU 1 sets level to 1.
CPU 1 calls kvm_ioapic_set_irq(1). CPU 0 calls kvm_ioapic_set_irq(0).
No ioapic thinks the level is 0 but irq_state is not 0.

This untested and un-compiled patch should fix it.

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index ef91d79..e22c78b 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -825,7 +825,7 @@ int kvm_read_guest_page_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
 void kvm_propagate_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault);
 bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl);
 
-int kvm_pic_set_irq(void *opaque, int irq, int level);
+int kvm_pic_set_irq(void *opaque, int irq);
 
 void kvm_inject_nmi(struct kvm_vcpu *vcpu);
 
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
index 81cf4fa..0d6988f 100644
--- a/arch/x86/kvm/i8259.c
+++ b/arch/x86/kvm/i8259.c
@@ -188,12 +188,13 @@ void kvm_pic_update_irq(struct kvm_pic *s)
 	pic_unlock(s);
 }
 
-int kvm_pic_set_irq(void *opaque, int irq, int level)
+int kvm_pic_set_irq(void *opaque, int irq)
 {
 	struct kvm_pic *s = opaque;
-	int ret = -1;
+	int ret = -1, level;
 
 	pic_lock(s);
+	level = !!s->irq_states[irq];
 	if (irq >= 0 && irq < PIC_NUM_PINS) {
 		ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
 		pic_update_irq(s);
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index 26fd54d..6ad6a6b 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -191,14 +191,15 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
 	return kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe);
 }
 
-int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level)
+int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq)
 {
 	u32 old_irr;
 	u32 mask = 1 << irq;
 	union kvm_ioapic_redirect_entry entry;
-	int ret = 1;
+	int ret = 1, level;
 
 	spin_lock(&ioapic->lock);
+	level = !!ioapic->irq_states[irq];
 	old_irr = ioapic->irr;
 	if (irq >= 0 && irq < IOAPIC_NUM_PINS) {
 		entry = ioapic->redirtbl[irq];
diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h
index 32872a0..65894dd 100644
--- a/virt/kvm/ioapic.h
+++ b/virt/kvm/ioapic.h
@@ -74,7 +74,7 @@ void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode);
 bool kvm_ioapic_handles_vector(struct kvm *kvm, int vector);
 int kvm_ioapic_init(struct kvm *kvm);
 void kvm_ioapic_destroy(struct kvm *kvm);
-int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level);
+int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq);
 void kvm_ioapic_reset(struct kvm_ioapic *ioapic);
 int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
 		struct kvm_lapic_irq *irq);
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
index a6a0365..db0ccef 100644
--- a/virt/kvm/irq_comm.c
+++ b/virt/kvm/irq_comm.c
@@ -33,7 +33,7 @@
 
 #include "ioapic.h"
 
-static inline int kvm_irq_line_state(unsigned long *irq_state,
+static inline void kvm_irq_line_state(unsigned long *irq_state,
 				     int irq_source_id, int level)
 {
 	/* Logical OR for level trig interrupt */
@@ -41,8 +41,6 @@ static inline int kvm_irq_line_state(unsigned long *irq_state,
 		set_bit(irq_source_id, irq_state);
 	else
 		clear_bit(irq_source_id, irq_state);
-
-	return !!(*irq_state);
 }
 
 static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
@@ -50,9 +48,9 @@ static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
 {
 #ifdef CONFIG_X86
 	struct kvm_pic *pic = pic_irqchip(kvm);
-	level = kvm_irq_line_state(&pic->irq_states[e->irqchip.pin],
+	kvm_irq_line_state(&pic->irq_states[e->irqchip.pin],
 				   irq_source_id, level);
-	return kvm_pic_set_irq(pic, e->irqchip.pin, level);
+	return kvm_pic_set_irq(pic, e->irqchip.pin);
 #else
 	return -1;
 #endif
@@ -62,10 +60,10 @@ static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e,
 			      struct kvm *kvm, int irq_source_id, int level)
 {
 	struct kvm_ioapic *ioapic = kvm->arch.vioapic;
-	level = kvm_irq_line_state(&ioapic->irq_states[e->irqchip.pin],
+	kvm_irq_line_state(&ioapic->irq_states[e->irqchip.pin],
 				   irq_source_id, level);
 
-	return kvm_ioapic_set_irq(ioapic, e->irqchip.pin, level);
+	return kvm_ioapic_set_irq(ioapic, e->irqchip.pin);
 }
 
 inline static bool kvm_is_dm_lowest_prio(struct kvm_lapic_irq *irq)

--
			Gleb.

  parent reply	other threads:[~2012-07-18  6:27 UTC|newest]

Thread overview: 96+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-16 20:33 [PATCH v5 0/4] kvm: level irqfd and new eoifd Alex Williamson
2012-07-16 20:33 ` [PATCH v5 1/4] kvm: Extend irqfd to support level interrupts Alex Williamson
2012-07-17 21:26   ` Michael S. Tsirkin
2012-07-17 21:57     ` Alex Williamson
2012-07-17 22:00       ` Michael S. Tsirkin
2012-07-17 22:16         ` Alex Williamson
2012-07-17 22:28           ` Michael S. Tsirkin
2012-07-18 10:41   ` Michael S. Tsirkin
2012-07-18 10:44     ` Gleb Natapov
2012-07-18 10:48       ` Michael S. Tsirkin
2012-07-18 10:49         ` Gleb Natapov
2012-07-18 10:53           ` Michael S. Tsirkin
2012-07-18 10:55             ` Gleb Natapov
2012-07-18 11:22               ` Michael S. Tsirkin
2012-07-18 11:39                 ` Michael S. Tsirkin
2012-07-18 11:48                   ` Gleb Natapov
2012-07-18 12:07                     ` Michael S. Tsirkin
2012-07-18 14:47                       ` Alex Williamson
2012-07-18 15:38                         ` Michael S. Tsirkin
2012-07-18 15:48                           ` Alex Williamson
2012-07-18 15:58                             ` Michael S. Tsirkin
2012-07-18 18:42                               ` Marcelo Tosatti
2012-07-18 19:00                                 ` Gleb Natapov
2012-07-18 19:07                                 ` Alex Williamson
2012-07-18 19:13                                   ` Alex Williamson
2012-07-18 19:16                                     ` Michael S. Tsirkin
2012-07-18 20:28                                     ` Alex Williamson
2012-07-18 21:23                                       ` Marcelo Tosatti
2012-07-18 21:30                                         ` Michael S. Tsirkin
2012-07-16 20:33 ` [PATCH v5 2/4] kvm: KVM_EOIFD, an eventfd for EOIs Alex Williamson
2012-07-17 10:21   ` Michael S. Tsirkin
2012-07-17 13:59     ` Alex Williamson
2012-07-17 14:10       ` Michael S. Tsirkin
2012-07-17 14:29         ` Alex Williamson
2012-07-17 14:42           ` Michael S. Tsirkin
2012-07-17 14:57             ` Alex Williamson
2012-07-17 15:13               ` Michael S. Tsirkin
2012-07-17 15:41                 ` Alex Williamson
2012-07-17 15:53                   ` Michael S. Tsirkin
2012-07-17 16:06                     ` Alex Williamson
2012-07-17 16:19                       ` Michael S. Tsirkin
2012-07-17 16:52                         ` Alex Williamson
2012-07-17 18:58                           ` Michael S. Tsirkin
2012-07-17 20:03                             ` Alex Williamson
2012-07-17 21:23                               ` Michael S. Tsirkin
2012-07-17 22:09                                 ` Alex Williamson
2012-07-17 22:24                                   ` Michael S. Tsirkin
2012-07-18  2:44                                     ` Alex Williamson
2012-07-18 10:31                                       ` Michael S. Tsirkin
2012-07-16 20:34 ` [PATCH v5 3/4] kvm: Create kvm_clear_irq() Alex Williamson
2012-07-17  0:51   ` Michael S. Tsirkin
2012-07-17  2:42     ` Alex Williamson
2012-07-17  0:55   ` Michael S. Tsirkin
2012-07-17 10:14   ` Michael S. Tsirkin
2012-07-17 13:56     ` Alex Williamson
2012-07-17 14:08       ` Michael S. Tsirkin
2012-07-17 14:21         ` Alex Williamson
2012-07-17 14:53           ` Michael S. Tsirkin
2012-07-17 15:20             ` Alex Williamson
2012-07-17 15:36               ` Michael S. Tsirkin
2012-07-17 15:51                 ` Alex Williamson
2012-07-17 15:57                   ` Michael S. Tsirkin
2012-07-17 16:01                     ` Gleb Natapov
2012-07-17 16:08                     ` Alex Williamson
2012-07-17 16:14                       ` Michael S. Tsirkin
2012-07-17 16:17                         ` Alex Williamson
2012-07-17 16:21                           ` Michael S. Tsirkin
2012-07-17 16:45                             ` Alex Williamson
2012-07-17 18:55                               ` Michael S. Tsirkin
2012-07-17 19:51                                 ` Alex Williamson
2012-07-17 21:05                                   ` Michael S. Tsirkin
2012-07-17 22:01                                     ` Alex Williamson
2012-07-17 22:05                                       ` Michael S. Tsirkin
2012-07-17 22:22                                         ` Alex Williamson
2012-07-17 22:31                                           ` Michael S. Tsirkin
2012-07-18  6:27                         ` Gleb Natapov [this message]
2012-07-18 10:20                           ` Michael S. Tsirkin
2012-07-18 10:27                             ` Gleb Natapov
2012-07-18 10:33                               ` Michael S. Tsirkin
2012-07-18 10:36                                 ` Gleb Natapov
2012-07-18 10:51                                   ` Michael S. Tsirkin
2012-07-18 10:53                                     ` Gleb Natapov
2012-07-18 11:08                                       ` Michael S. Tsirkin
2012-07-18 11:50                                         ` Gleb Natapov
2012-07-18 21:55                           ` Michael S. Tsirkin
2012-07-17 16:36                       ` Michael S. Tsirkin
2012-07-17 17:09                         ` Gleb Natapov
2012-07-17 10:18   ` Michael S. Tsirkin
2012-07-16 20:34 ` [PATCH v5 4/4] kvm: Convert eoifd to use kvm_clear_irq Alex Williamson
2012-07-18 10:43 ` [PATCH v5 0/4] kvm: level irqfd and new eoifd Michael S. Tsirkin
2012-07-19 16:59 ` Michael S. Tsirkin
2012-07-19 17:29   ` Alex Williamson
2012-07-19 17:45     ` Michael S. Tsirkin
2012-07-19 18:48       ` Alex Williamson
2012-07-20 10:07         ` Michael S. Tsirkin
2012-07-22 15:09           ` Gleb Natapov

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=20120718062742.GH6479@redhat.com \
    --to=gleb@redhat.com \
    --cc=alex.williamson@redhat.com \
    --cc=avi@redhat.com \
    --cc=jan.kiszka@siemens.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mst@redhat.com \
    /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.