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 09/42] KVM: Move irq sharing information to irqchip level
Date: Mon, 16 Nov 2009 14:19:10 +0200	[thread overview]
Message-ID: <1258373983-8693-10-git-send-email-avi@redhat.com> (raw)
In-Reply-To: <1258373983-8693-1-git-send-email-avi@redhat.com>

From: Gleb Natapov <gleb@redhat.com>

This removes assumptions that max GSIs is smaller than number of pins.
Sharing is tracked on pin level not GSI level.

[avi: no PIC on ia64]

Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/include/asm/kvm_host.h |    1 -
 arch/x86/kvm/irq.h              |    1 +
 include/linux/kvm_host.h        |    2 +-
 virt/kvm/ioapic.h               |    1 +
 virt/kvm/irq_comm.c             |   59 +++++++++++++++++++++++---------------
 5 files changed, 39 insertions(+), 25 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 0b113f2..35d3236 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -410,7 +410,6 @@ struct kvm_arch{
 	gpa_t ept_identity_map_addr;
 
 	unsigned long irq_sources_bitmap;
-	unsigned long irq_states[KVM_IOAPIC_NUM_PINS];
 	u64 vm_init_tsc;
 };
 
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h
index 7d6058a..c025a23 100644
--- a/arch/x86/kvm/irq.h
+++ b/arch/x86/kvm/irq.h
@@ -71,6 +71,7 @@ struct kvm_pic {
 	int output;		/* intr from master PIC */
 	struct kvm_io_device dev;
 	void (*ack_notifier)(void *opaque, int irq);
+	unsigned long irq_states[16];
 };
 
 struct kvm_pic *kvm_create_pic(struct kvm *kvm);
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index b7bbb5d..1c7f8c4 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -120,7 +120,7 @@ struct kvm_kernel_irq_routing_entry {
 	u32 gsi;
 	u32 type;
 	int (*set)(struct kvm_kernel_irq_routing_entry *e,
-		    struct kvm *kvm, int level);
+		   struct kvm *kvm, int irq_source_id, int level);
 	union {
 		struct {
 			unsigned irqchip;
diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h
index 7080b71..6e461ad 100644
--- a/virt/kvm/ioapic.h
+++ b/virt/kvm/ioapic.h
@@ -41,6 +41,7 @@ struct kvm_ioapic {
 	u32 irr;
 	u32 pad;
 	union kvm_ioapic_redirect_entry redirtbl[IOAPIC_NUM_PINS];
+	unsigned long irq_states[IOAPIC_NUM_PINS];
 	struct kvm_io_device dev;
 	struct kvm *kvm;
 	void (*ack_notifier)(void *opaque, int irq);
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
index 001663f..9783f5c 100644
--- a/virt/kvm/irq_comm.c
+++ b/virt/kvm/irq_comm.c
@@ -31,20 +31,39 @@
 
 #include "ioapic.h"
 
+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);
+}
+
 static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
-			   struct kvm *kvm, int level)
+			   struct kvm *kvm, int irq_source_id, int level)
 {
 #ifdef CONFIG_X86
-	return kvm_pic_set_irq(pic_irqchip(kvm), e->irqchip.pin, level);
+	struct kvm_pic *pic = pic_irqchip(kvm);
+	level = kvm_irq_line_state(&pic->irq_states[e->irqchip.pin],
+				   irq_source_id, level);
+	return kvm_pic_set_irq(pic, e->irqchip.pin, level);
 #else
 	return -1;
 #endif
 }
 
 static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e,
-			      struct kvm *kvm, int level)
+			      struct kvm *kvm, int irq_source_id, int level)
 {
-	return kvm_ioapic_set_irq(kvm->arch.vioapic, e->irqchip.pin, level);
+	struct kvm_ioapic *ioapic = kvm->arch.vioapic;
+	level = kvm_irq_line_state(&ioapic->irq_states[e->irqchip.pin],
+				   irq_source_id, level);
+
+	return kvm_ioapic_set_irq(ioapic, e->irqchip.pin, level);
 }
 
 inline static bool kvm_is_dm_lowest_prio(struct kvm_lapic_irq *irq)
@@ -96,10 +115,13 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
 }
 
 static int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
-		       struct kvm *kvm, int level)
+		       struct kvm *kvm, int irq_source_id, int level)
 {
 	struct kvm_lapic_irq irq;
 
+	if (!level)
+		return -1;
+
 	trace_kvm_msi_set_irq(e->msi.address_lo, e->msi.data);
 
 	irq.dest_id = (e->msi.address_lo &
@@ -125,34 +147,19 @@ static int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
 int kvm_set_irq(struct kvm *kvm, int irq_source_id, int irq, int level)
 {
 	struct kvm_kernel_irq_routing_entry *e;
-	unsigned long *irq_state, sig_level;
 	int ret = -1;
 
 	trace_kvm_set_irq(irq, level, irq_source_id);
 
 	WARN_ON(!mutex_is_locked(&kvm->irq_lock));
 
-	if (irq < KVM_IOAPIC_NUM_PINS) {
-		irq_state = (unsigned long *)&kvm->arch.irq_states[irq];
-
-		/* Logical OR for level trig interrupt */
-		if (level)
-			set_bit(irq_source_id, irq_state);
-		else
-			clear_bit(irq_source_id, irq_state);
-		sig_level = !!(*irq_state);
-	} else if (!level)
-		return ret;
-	else /* Deal with MSI/MSI-X */
-		sig_level = 1;
-
 	/* Not possible to detect if the guest uses the PIC or the
 	 * IOAPIC.  So set the bit in both. The guest will ignore
 	 * writes to the unused one.
 	 */
 	list_for_each_entry(e, &kvm->irq_routing, link)
 		if (e->gsi == irq) {
-			int r = e->set(e, kvm, sig_level);
+			int r = e->set(e, kvm, irq_source_id, level);
 			if (r < 0)
 				continue;
 
@@ -232,8 +239,14 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id)
 		printk(KERN_ERR "kvm: IRQ source ID out of range!\n");
 		return;
 	}
-	for (i = 0; i < KVM_IOAPIC_NUM_PINS; i++)
-		clear_bit(irq_source_id, &kvm->arch.irq_states[i]);
+	for (i = 0; i < KVM_IOAPIC_NUM_PINS; i++) {
+		clear_bit(irq_source_id, &kvm->arch.vioapic->irq_states[i]);
+		if (i >= 16)
+			continue;
+#ifdef CONFIG_X86
+		clear_bit(irq_source_id, &pic_irqchip(kvm)->irq_states[i]);
+#endif
+	}
 	clear_bit(irq_source_id, &kvm->arch.irq_sources_bitmap);
 	mutex_unlock(&kvm->irq_lock);
 }
-- 
1.6.5.2


  parent reply	other threads:[~2009-11-16 12:21 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-11-16 12:19 [PATCH 00/42] KVM updates for the 2.6.33 merge window (batch 1/2) Avi Kivity
2009-11-16 12:19 ` [PATCH 01/42] core, x86: Add user return notifiers Avi Kivity
2009-11-16 12:19 ` [PATCH 02/42] x86: Fix user return notifier build Avi Kivity
2009-11-16 12:19 ` [PATCH 03/42] x86: Fix user return notifier put_cpu_var() invocation Avi Kivity
2009-11-16 12:19 ` [PATCH 04/42] KVM: Don't wrap schedule() with vcpu_put()/vcpu_load() Avi Kivity
2009-11-16 12:19 ` [PATCH 05/42] KVM: x86 emulator: Add 'push/pop sreg' instructions Avi Kivity
2009-11-16 12:19 ` [PATCH 06/42] KVM: x86 emulator: Introduce No64 decode option Avi Kivity
2009-11-16 12:19 ` [PATCH 07/42] KVM: Don't pass kvm_run arguments Avi Kivity
2009-11-16 12:19 ` [PATCH 08/42] KVM: Call pic_clear_isr() on pic reset to reuse logic there Avi Kivity
2009-11-16 12:19 ` Avi Kivity [this message]
2009-11-16 12:19 ` [PATCH 10/42] KVM: Change irq routing table to use gsi indexed array Avi Kivity
2009-11-16 12:19 ` [PATCH 11/42] KVM: Maintain back mapping from irqchip/pin to gsi Avi Kivity
2009-11-16 12:19 ` [PATCH 12/42] KVM: Move irq routing data structure to rcu locking Avi Kivity
2009-11-16 12:19 ` [PATCH 13/42] KVM: Move irq ack notifier list to arch independent code Avi Kivity
2009-11-16 12:19 ` [PATCH 14/42] KVM: Convert irq notifiers lists to RCU locking Avi Kivity
2009-11-16 12:19 ` [PATCH 15/42] KVM: Move IO APIC to its own lock Avi Kivity
2009-11-16 12:19 ` [PATCH 16/42] KVM: Drop kvm->irq_lock lock from irq injection path Avi Kivity
2009-11-16 12:19 ` [PATCH 17/42] KVM: Return -ENOTTY on unrecognized ioctls Avi Kivity
2009-11-16 12:19 ` [PATCH 18/42] KVM: Move assigned device code to own file Avi Kivity
2009-11-16 12:19 ` [PATCH 19/42] KVM: x86 emulator: Add missing decoder flags for 'or' instructions Avi Kivity
2009-11-16 12:19 ` [PATCH 20/42] KVM: x86 emulator: Add pusha and popa instructions Avi Kivity
2009-11-16 12:19 ` [PATCH 21/42] KVM: VMX: Enhance invalid guest state emulation Avi Kivity
2009-11-16 12:19 ` [PATCH 22/42] KVM: SVM: remove needless mmap_sem acquision from nested_svm_map Avi Kivity
2009-11-16 12:19 ` [PATCH 23/42] KVM: Activate Virtualization On Demand Avi Kivity
2010-03-17 21:57   ` Dieter Ries
2010-03-17 22:02     ` Alexander Graf
2010-03-17 22:40       ` Dieter Ries
2010-03-17 22:47         ` Alexander Graf
2010-03-18  7:11           ` Dieter Ries
2010-03-18  7:17             ` Alexander Graf
2010-03-19  2:26               ` Dieter Ries
2010-08-08 12:02               ` Serge Belyshev
2010-08-16 13:24                 ` Alexander Graf
2010-08-16 13:49                   ` Serge Belyshev
2010-08-16 14:13                     ` Alexander Graf
2010-03-18  5:41         ` Michael Tokarev
2010-03-18  7:04           ` Dieter Ries
2009-11-16 12:19 ` [PATCH 24/42] KVM: remove duplicated #include Avi Kivity
2009-11-16 12:19 ` [PATCH 25/42] KVM: SVM: reorganize svm_interrupt_allowed Avi Kivity
2009-11-16 12:19 ` [PATCH 26/42] KVM: SVM: don't copy exit_int_info on nested vmrun Avi Kivity
2009-11-16 12:19 ` [PATCH 27/42] KVM: SVM: Remove remaining occurences of rdtscll Avi Kivity
2009-11-16 12:19 ` [PATCH 28/42] KVM: fix lock imbalance in kvm_*_irq_source_id() Avi Kivity
2009-11-16 12:19 ` [PATCH 29/42] KVM: Separate timer intialization into an indepedent function Avi Kivity
2009-11-16 12:19 ` [PATCH 30/42] KVM: Kill the confusing tsc_ref_khz and ref_freq variables Avi Kivity
2009-11-16 12:19 ` [PATCH 31/42] KVM: Fix printk name error in svm.c Avi Kivity
2009-11-16 12:19 ` [PATCH 32/42] KVM: Fix hotplug of CPUs Avi Kivity
2009-11-16 12:19 ` [PATCH 33/42] KVM: remove pre_task_link setting in save_state_to_tss16 Avi Kivity
2009-11-16 12:19 ` [PATCH 34/42] KVM: x86: Refactor guest debug IOCTL handling Avi Kivity
2009-11-16 12:19 ` [PATCH 35/42] KVM: x86: disable paravirt mmu reporting Avi Kivity
2009-11-16 12:19 ` [PATCH 36/42] KVM: x86: Rework guest single-step flag injection and filtering Avi Kivity
2009-11-16 12:19 ` [PATCH 37/42] KVM: x86: include pvclock MSRs in msrs_to_save Avi Kivity
2009-11-16 12:19 ` [PATCH 38/42] KVM: SVM: Notify nested hypervisor of lost event injections Avi Kivity
2009-11-16 12:19 ` [PATCH 39/42] KVM: SVM: Move INTR vmexit out of atomic code Avi Kivity
2009-11-16 12:19 ` [PATCH 40/42] KVM: SVM: Add tracepoint for nested vmrun Avi Kivity
2009-11-16 12:19 ` [PATCH 41/42] KVM: SVM: Add tracepoint for nested #vmexit Avi Kivity
2009-11-16 12:19 ` [PATCH 42/42] KVM: SVM: Add tracepoint for injected #vmexit Avi Kivity

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=1258373983-8693-10-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.