All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] IRQFD without IRQ routing, enabled for XICS
@ 2014-06-30 10:51 ` Paul Mackerras
  0 siblings, 0 replies; 30+ messages in thread
From: Paul Mackerras @ 2014-06-30 10:51 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: Michael S. Tsirkin, Alexander Graf, Eric Auger

This series of patches provides a way to implement IRQFD support
without having to implement IRQ routing, and adds IRQFD support for
the XICS interrupt controller emulation.  (XICS is the interrupt
controller defined for the pSeries machine type, used on IBM POWER
servers).

The basic approach is to make it easy for code other than irqchip.c to
provide a mapping from a global interrupt number (GSI) to an irq
routing entry (struct kvm_kernel_irq_routing_entry).  To make the
lifetime of this routing entry easier to manage, we change the IRQFD
code to keep a copy of the routing entry (for the MSI fast-path case)
rather than a pointer to the routing entry.  Since the copy can't be
updated atomically, we add a seqcount_t to make sure that when reading
it we get a copy that hasn't been half-way updated.

Next we replace the hard-coded accesses outside irqchip.c to the
fields of the kvm_irq_routing_table struct with calls to accessor
functions in irqchip.c, namely kvm_irq_map_gsi() and
kvm_irq_map_chip_pin().  That enables us to move all references to the
kvm_irq_routing_table struct, and the definition of that struct, into
irqchip.c.

Then we move the irq notifier implementation from irqchip.c into
eventfd.c and add a separate Kconfig option to enable IRQFD.  With
that we can enable IRQFD without irq routing, which we achieve by
compiling in eventfd.c but not irqchip.c, and providing an alternative
implementation of kvm_irq_map_gsi() and kvm_irq_map_chip_pin().

The last patch does that for XICS.  With this series I can use
vhost-net with KVM guests, and I see the TCP bandwidth between guest
and host on a POWER8 machine go from around 700MB/s to over 2GB/s.

I would like to see this go into 3.17.

 arch/ia64/kvm/Kconfig                |   1 +
 arch/powerpc/kvm/Kconfig             |   3 +
 arch/powerpc/kvm/book3s_hv_rm_xics.c |   5 ++
 arch/powerpc/kvm/book3s_xics.c       |  55 +++++++++++---
 arch/powerpc/kvm/book3s_xics.h       |   2 +
 arch/powerpc/kvm/mpic.c              |   4 +-
 arch/s390/kvm/Kconfig                |   1 +
 arch/s390/kvm/interrupt.c            |   3 +-
 arch/x86/kvm/Kconfig                 |   1 +
 include/linux/kvm_host.h             |  43 ++++-------
 virt/kvm/Kconfig                     |   3 +
 virt/kvm/eventfd.c                   | 134 ++++++++++++++++++++++++++---------
 virt/kvm/irq_comm.c                  |  24 +++----
 virt/kvm/irqchip.c                   |  98 ++++++++++---------------
 virt/kvm/kvm_main.c                  |   2 +-
 15 files changed, 227 insertions(+), 152 deletions(-)

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 0/6] IRQFD without IRQ routing, enabled for XICS
@ 2014-06-30 10:51 ` Paul Mackerras
  0 siblings, 0 replies; 30+ messages in thread
From: Paul Mackerras @ 2014-06-30 10:51 UTC (permalink / raw)
  To: kvm, kvm-ppc; +Cc: Michael S. Tsirkin, Alexander Graf, Eric Auger

This series of patches provides a way to implement IRQFD support
without having to implement IRQ routing, and adds IRQFD support for
the XICS interrupt controller emulation.  (XICS is the interrupt
controller defined for the pSeries machine type, used on IBM POWER
servers).

The basic approach is to make it easy for code other than irqchip.c to
provide a mapping from a global interrupt number (GSI) to an irq
routing entry (struct kvm_kernel_irq_routing_entry).  To make the
lifetime of this routing entry easier to manage, we change the IRQFD
code to keep a copy of the routing entry (for the MSI fast-path case)
rather than a pointer to the routing entry.  Since the copy can't be
updated atomically, we add a seqcount_t to make sure that when reading
it we get a copy that hasn't been half-way updated.

Next we replace the hard-coded accesses outside irqchip.c to the
fields of the kvm_irq_routing_table struct with calls to accessor
functions in irqchip.c, namely kvm_irq_map_gsi() and
kvm_irq_map_chip_pin().  That enables us to move all references to the
kvm_irq_routing_table struct, and the definition of that struct, into
irqchip.c.

Then we move the irq notifier implementation from irqchip.c into
eventfd.c and add a separate Kconfig option to enable IRQFD.  With
that we can enable IRQFD without irq routing, which we achieve by
compiling in eventfd.c but not irqchip.c, and providing an alternative
implementation of kvm_irq_map_gsi() and kvm_irq_map_chip_pin().

The last patch does that for XICS.  With this series I can use
vhost-net with KVM guests, and I see the TCP bandwidth between guest
and host on a POWER8 machine go from around 700MB/s to over 2GB/s.

I would like to see this go into 3.17.

 arch/ia64/kvm/Kconfig                |   1 +
 arch/powerpc/kvm/Kconfig             |   3 +
 arch/powerpc/kvm/book3s_hv_rm_xics.c |   5 ++
 arch/powerpc/kvm/book3s_xics.c       |  55 +++++++++++---
 arch/powerpc/kvm/book3s_xics.h       |   2 +
 arch/powerpc/kvm/mpic.c              |   4 +-
 arch/s390/kvm/Kconfig                |   1 +
 arch/s390/kvm/interrupt.c            |   3 +-
 arch/x86/kvm/Kconfig                 |   1 +
 include/linux/kvm_host.h             |  43 ++++-------
 virt/kvm/Kconfig                     |   3 +
 virt/kvm/eventfd.c                   | 134 ++++++++++++++++++++++++++---------
 virt/kvm/irq_comm.c                  |  24 +++----
 virt/kvm/irqchip.c                   |  98 ++++++++++---------------
 virt/kvm/kvm_main.c                  |   2 +-
 15 files changed, 227 insertions(+), 152 deletions(-)

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 1/6] KVM: Don't keep reference to irq routing table in irqfd struct
  2014-06-30 10:51 ` Paul Mackerras
@ 2014-06-30 10:51   ` Paul Mackerras
  -1 siblings, 0 replies; 30+ messages in thread
From: Paul Mackerras @ 2014-06-30 10:51 UTC (permalink / raw)
  To: kvm, kvm-ppc
  Cc: Michael S. Tsirkin, Alexander Graf, Eric Auger, Paul Mackerras

This makes the irqfd code keep a copy of the irq routing table entry
for each irqfd, rather than a reference to the copy in the actual
irq routing table maintained in kvm/virt/irqchip.c.  This will enable
us to change the routing table structure in future, or even not have a
routing table at all on some platforms.

The synchronization that was previously achieved using srcu_dereference
on the read side is now achieved using a seqcount_t structure.  That
ensures that we don't get a halfway-updated copy of the structure if
we read it while another thread is updating it.

We still use srcu_read_lock/unlock around the read side so that when
changing the routing table we can be sure that after calling
synchronize_srcu, nothing will be using the old routing.

Signed-off-by: Paul Mackerras <paulus@samba.org>
---
 virt/kvm/eventfd.c | 41 +++++++++++++++++++++++++----------------
 1 file changed, 25 insertions(+), 16 deletions(-)

diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 20c3af7..bae593a 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -33,6 +33,7 @@
 #include <linux/kernel.h>
 #include <linux/srcu.h>
 #include <linux/slab.h>
+#include <linux/seqlock.h>
 
 #include "iodev.h"
 
@@ -75,7 +76,8 @@ struct _irqfd {
 	struct kvm *kvm;
 	wait_queue_t wait;
 	/* Update side is protected by irqfds.lock */
-	struct kvm_kernel_irq_routing_entry __rcu *irq_entry;
+	struct kvm_kernel_irq_routing_entry irq_entry;
+	seqcount_t irq_entry_sc;
 	/* Used for level IRQ fast-path */
 	int gsi;
 	struct work_struct inject;
@@ -223,16 +225,20 @@ irqfd_wakeup(wait_queue_t *wait, unsigned mode, int sync, void *key)
 {
 	struct _irqfd *irqfd = container_of(wait, struct _irqfd, wait);
 	unsigned long flags = (unsigned long)key;
-	struct kvm_kernel_irq_routing_entry *irq;
+	struct kvm_kernel_irq_routing_entry irq;
 	struct kvm *kvm = irqfd->kvm;
+	unsigned seq;
 	int idx;
 
 	if (flags & POLLIN) {
 		idx = srcu_read_lock(&kvm->irq_srcu);
-		irq = srcu_dereference(irqfd->irq_entry, &kvm->irq_srcu);
+		do {
+			seq = read_seqcount_begin(&irqfd->irq_entry_sc);
+			irq = irqfd->irq_entry;
+		} while (read_seqcount_retry(&irqfd->irq_entry_sc, seq));
 		/* An event has been signaled, inject an interrupt */
-		if (irq)
-			kvm_set_msi(irq, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1,
+		if (irq.type == KVM_IRQ_ROUTING_MSI)
+			kvm_set_msi(&irq, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1,
 					false);
 		else
 			schedule_work(&irqfd->inject);
@@ -277,18 +283,20 @@ static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd,
 {
 	struct kvm_kernel_irq_routing_entry *e;
 
-	if (irqfd->gsi >= irq_rt->nr_rt_entries) {
-		rcu_assign_pointer(irqfd->irq_entry, NULL);
-		return;
-	}
+	write_seqcount_begin(&irqfd->irq_entry_sc);
+
+	irqfd->irq_entry.type = 0;
+	if (irqfd->gsi >= irq_rt->nr_rt_entries)
+		goto out;
 
 	hlist_for_each_entry(e, &irq_rt->map[irqfd->gsi], link) {
 		/* Only fast-path MSI. */
 		if (e->type == KVM_IRQ_ROUTING_MSI)
-			rcu_assign_pointer(irqfd->irq_entry, e);
-		else
-			rcu_assign_pointer(irqfd->irq_entry, NULL);
+			irqfd->irq_entry = *e;
 	}
+
+ out:
+	write_seqcount_end(&irqfd->irq_entry_sc);
 }
 
 static int
@@ -310,6 +318,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
 	INIT_LIST_HEAD(&irqfd->list);
 	INIT_WORK(&irqfd->inject, irqfd_inject);
 	INIT_WORK(&irqfd->shutdown, irqfd_shutdown);
+	seqcount_init(&irqfd->irq_entry_sc);
 
 	f = fdget(args->fd);
 	if (!f.file) {
@@ -466,14 +475,14 @@ kvm_irqfd_deassign(struct kvm *kvm, struct kvm_irqfd *args)
 	list_for_each_entry_safe(irqfd, tmp, &kvm->irqfds.items, list) {
 		if (irqfd->eventfd == eventfd && irqfd->gsi == args->gsi) {
 			/*
-			 * This rcu_assign_pointer is needed for when
+			 * This clearing of irq_entry.type is needed for when
 			 * another thread calls kvm_irq_routing_update before
 			 * we flush workqueue below (we synchronize with
 			 * kvm_irq_routing_update using irqfds.lock).
-			 * It is paired with synchronize_srcu done by caller
-			 * of that function.
 			 */
-			rcu_assign_pointer(irqfd->irq_entry, NULL);
+			write_seqcount_begin(&irqfd->irq_entry_sc);
+			irqfd->irq_entry.type = 0;
+			write_seqcount_end(&irqfd->irq_entry_sc);
 			irqfd_deactivate(irqfd);
 		}
 	}
-- 
2.0.0

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 1/6] KVM: Don't keep reference to irq routing table in irqfd struct
@ 2014-06-30 10:51   ` Paul Mackerras
  0 siblings, 0 replies; 30+ messages in thread
From: Paul Mackerras @ 2014-06-30 10:51 UTC (permalink / raw)
  To: kvm, kvm-ppc
  Cc: Michael S. Tsirkin, Alexander Graf, Eric Auger, Paul Mackerras

This makes the irqfd code keep a copy of the irq routing table entry
for each irqfd, rather than a reference to the copy in the actual
irq routing table maintained in kvm/virt/irqchip.c.  This will enable
us to change the routing table structure in future, or even not have a
routing table at all on some platforms.

The synchronization that was previously achieved using srcu_dereference
on the read side is now achieved using a seqcount_t structure.  That
ensures that we don't get a halfway-updated copy of the structure if
we read it while another thread is updating it.

We still use srcu_read_lock/unlock around the read side so that when
changing the routing table we can be sure that after calling
synchronize_srcu, nothing will be using the old routing.

Signed-off-by: Paul Mackerras <paulus@samba.org>
---
 virt/kvm/eventfd.c | 41 +++++++++++++++++++++++++----------------
 1 file changed, 25 insertions(+), 16 deletions(-)

diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 20c3af7..bae593a 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -33,6 +33,7 @@
 #include <linux/kernel.h>
 #include <linux/srcu.h>
 #include <linux/slab.h>
+#include <linux/seqlock.h>
 
 #include "iodev.h"
 
@@ -75,7 +76,8 @@ struct _irqfd {
 	struct kvm *kvm;
 	wait_queue_t wait;
 	/* Update side is protected by irqfds.lock */
-	struct kvm_kernel_irq_routing_entry __rcu *irq_entry;
+	struct kvm_kernel_irq_routing_entry irq_entry;
+	seqcount_t irq_entry_sc;
 	/* Used for level IRQ fast-path */
 	int gsi;
 	struct work_struct inject;
@@ -223,16 +225,20 @@ irqfd_wakeup(wait_queue_t *wait, unsigned mode, int sync, void *key)
 {
 	struct _irqfd *irqfd = container_of(wait, struct _irqfd, wait);
 	unsigned long flags = (unsigned long)key;
-	struct kvm_kernel_irq_routing_entry *irq;
+	struct kvm_kernel_irq_routing_entry irq;
 	struct kvm *kvm = irqfd->kvm;
+	unsigned seq;
 	int idx;
 
 	if (flags & POLLIN) {
 		idx = srcu_read_lock(&kvm->irq_srcu);
-		irq = srcu_dereference(irqfd->irq_entry, &kvm->irq_srcu);
+		do {
+			seq = read_seqcount_begin(&irqfd->irq_entry_sc);
+			irq = irqfd->irq_entry;
+		} while (read_seqcount_retry(&irqfd->irq_entry_sc, seq));
 		/* An event has been signaled, inject an interrupt */
-		if (irq)
-			kvm_set_msi(irq, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1,
+		if (irq.type = KVM_IRQ_ROUTING_MSI)
+			kvm_set_msi(&irq, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1,
 					false);
 		else
 			schedule_work(&irqfd->inject);
@@ -277,18 +283,20 @@ static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd,
 {
 	struct kvm_kernel_irq_routing_entry *e;
 
-	if (irqfd->gsi >= irq_rt->nr_rt_entries) {
-		rcu_assign_pointer(irqfd->irq_entry, NULL);
-		return;
-	}
+	write_seqcount_begin(&irqfd->irq_entry_sc);
+
+	irqfd->irq_entry.type = 0;
+	if (irqfd->gsi >= irq_rt->nr_rt_entries)
+		goto out;
 
 	hlist_for_each_entry(e, &irq_rt->map[irqfd->gsi], link) {
 		/* Only fast-path MSI. */
 		if (e->type = KVM_IRQ_ROUTING_MSI)
-			rcu_assign_pointer(irqfd->irq_entry, e);
-		else
-			rcu_assign_pointer(irqfd->irq_entry, NULL);
+			irqfd->irq_entry = *e;
 	}
+
+ out:
+	write_seqcount_end(&irqfd->irq_entry_sc);
 }
 
 static int
@@ -310,6 +318,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
 	INIT_LIST_HEAD(&irqfd->list);
 	INIT_WORK(&irqfd->inject, irqfd_inject);
 	INIT_WORK(&irqfd->shutdown, irqfd_shutdown);
+	seqcount_init(&irqfd->irq_entry_sc);
 
 	f = fdget(args->fd);
 	if (!f.file) {
@@ -466,14 +475,14 @@ kvm_irqfd_deassign(struct kvm *kvm, struct kvm_irqfd *args)
 	list_for_each_entry_safe(irqfd, tmp, &kvm->irqfds.items, list) {
 		if (irqfd->eventfd = eventfd && irqfd->gsi = args->gsi) {
 			/*
-			 * This rcu_assign_pointer is needed for when
+			 * This clearing of irq_entry.type is needed for when
 			 * another thread calls kvm_irq_routing_update before
 			 * we flush workqueue below (we synchronize with
 			 * kvm_irq_routing_update using irqfds.lock).
-			 * It is paired with synchronize_srcu done by caller
-			 * of that function.
 			 */
-			rcu_assign_pointer(irqfd->irq_entry, NULL);
+			write_seqcount_begin(&irqfd->irq_entry_sc);
+			irqfd->irq_entry.type = 0;
+			write_seqcount_end(&irqfd->irq_entry_sc);
 			irqfd_deactivate(irqfd);
 		}
 	}
-- 
2.0.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 2/6] KVM: irqchip: Provide and use accessors for irq routing table
  2014-06-30 10:51 ` Paul Mackerras
@ 2014-06-30 10:51   ` Paul Mackerras
  -1 siblings, 0 replies; 30+ messages in thread
From: Paul Mackerras @ 2014-06-30 10:51 UTC (permalink / raw)
  To: kvm, kvm-ppc
  Cc: Michael S. Tsirkin, Alexander Graf, Eric Auger, Paul Mackerras

This provides accessor functions for the KVM interrupt mappings, in
order to reduce the amount of code that accesses the fields of the
kvm_irq_routing_table struct, and restrict that code to one file,
virt/kvm/irqchip.c.  The new functions are kvm_irq_map_gsi(), which
maps from a global interrupt number to a set of IRQ routing entries,
and kvm_irq_map_chip_pin, which maps from IRQ chip and pin numbers to
a global interrupt number.

This also moves the update of kvm_irq_routing_table::chip[][]
into irqchip.c, out of the various kvm_set_routing_entry
implementations.  That means that none of the kvm_set_routing_entry
implementations need the kvm_irq_routing_table argument anymore,
so this removes it.

This does not change any locking or data lifetime rules.

Signed-off-by: Paul Mackerras <paulus@samba.org>
---
 arch/powerpc/kvm/mpic.c   |  4 +---
 arch/s390/kvm/interrupt.c |  3 +--
 include/linux/kvm_host.h  |  8 ++++++--
 virt/kvm/eventfd.c        | 10 ++++++----
 virt/kvm/irq_comm.c       | 20 +++++++++-----------
 virt/kvm/irqchip.c        | 42 ++++++++++++++++++++++++++++++++++--------
 6 files changed, 57 insertions(+), 30 deletions(-)

diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c
index b68d0dc..39b3a8f 100644
--- a/arch/powerpc/kvm/mpic.c
+++ b/arch/powerpc/kvm/mpic.c
@@ -1826,8 +1826,7 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
 	return 0;
 }
 
-int kvm_set_routing_entry(struct kvm_irq_routing_table *rt,
-			  struct kvm_kernel_irq_routing_entry *e,
+int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e,
 			  const struct kvm_irq_routing_entry *ue)
 {
 	int r = -EINVAL;
@@ -1839,7 +1838,6 @@ int kvm_set_routing_entry(struct kvm_irq_routing_table *rt,
 		e->irqchip.pin = ue->u.irqchip.pin;
 		if (e->irqchip.pin >= KVM_IRQCHIP_NUM_PINS)
 			goto out;
-		rt->chip[ue->u.irqchip.irqchip][e->irqchip.pin] = ue->gsi;
 		break;
 	case KVM_IRQ_ROUTING_MSI:
 		e->set = kvm_set_msi;
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 90c8de2..cd1e754 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -1589,8 +1589,7 @@ static int set_adapter_int(struct kvm_kernel_irq_routing_entry *e,
 	return ret;
 }
 
-int kvm_set_routing_entry(struct kvm_irq_routing_table *rt,
-			  struct kvm_kernel_irq_routing_entry *e,
+int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e,
 			  const struct kvm_irq_routing_entry *ue)
 {
 	int ret;
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index ec4e3bd..4530753 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -752,6 +752,11 @@ void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
 void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
 			     bool mask);
 
+int kvm_irq_map_gsi(struct kvm_kernel_irq_routing_entry *entries,
+		    struct kvm_irq_routing_table *irq_rt, int gsi);
+int kvm_irq_map_chip_pin(struct kvm_irq_routing_table *irq_rt,
+			 unsigned irqchip, unsigned pin);
+
 int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
 		bool line_status);
 int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level);
@@ -942,8 +947,7 @@ int kvm_set_irq_routing(struct kvm *kvm,
 			const struct kvm_irq_routing_entry *entries,
 			unsigned nr,
 			unsigned flags);
-int kvm_set_routing_entry(struct kvm_irq_routing_table *rt,
-			  struct kvm_kernel_irq_routing_entry *e,
+int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e,
 			  const struct kvm_irq_routing_entry *ue);
 void kvm_free_irq_routing(struct kvm *kvm);
 
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index bae593a..15fa948 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -282,20 +282,22 @@ static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd,
 			 struct kvm_irq_routing_table *irq_rt)
 {
 	struct kvm_kernel_irq_routing_entry *e;
+	struct kvm_kernel_irq_routing_entry entries[KVM_NR_IRQCHIPS];
+	int i, n_entries;
+
+	n_entries = kvm_irq_map_gsi(entries, irq_rt, irqfd->gsi);
 
 	write_seqcount_begin(&irqfd->irq_entry_sc);
 
 	irqfd->irq_entry.type = 0;
-	if (irqfd->gsi >= irq_rt->nr_rt_entries)
-		goto out;
 
-	hlist_for_each_entry(e, &irq_rt->map[irqfd->gsi], link) {
+	e = entries;
+	for (i = 0; i < n_entries; ++i, ++e) {
 		/* Only fast-path MSI. */
 		if (e->type == KVM_IRQ_ROUTING_MSI)
 			irqfd->irq_entry = *e;
 	}
 
- out:
 	write_seqcount_end(&irqfd->irq_entry_sc);
 }
 
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
index ced4a54..6e73af2 100644
--- a/virt/kvm/irq_comm.c
+++ b/virt/kvm/irq_comm.c
@@ -160,6 +160,7 @@ static int kvm_set_msi_inatomic(struct kvm_kernel_irq_routing_entry *e,
  */
 int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level)
 {
+	struct kvm_kernel_irq_routing_entry entries[KVM_NR_IRQCHIPS];
 	struct kvm_kernel_irq_routing_entry *e;
 	int ret = -EINVAL;
 	struct kvm_irq_routing_table *irq_rt;
@@ -177,14 +178,13 @@ int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level)
 	 */
 	idx = srcu_read_lock(&kvm->irq_srcu);
 	irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
-	if (irq < irq_rt->nr_rt_entries)
-		hlist_for_each_entry(e, &irq_rt->map[irq], link) {
-			if (likely(e->type == KVM_IRQ_ROUTING_MSI))
-				ret = kvm_set_msi_inatomic(e, kvm);
-			else
-				ret = -EWOULDBLOCK;
-			break;
-		}
+	if (kvm_irq_map_gsi(entries, irq_rt, irq) > 0) {
+		e = &entries[0];
+		if (likely(e->type == KVM_IRQ_ROUTING_MSI))
+			ret = kvm_set_msi_inatomic(e, kvm);
+		else
+			ret = -EWOULDBLOCK;
+	}
 	srcu_read_unlock(&kvm->irq_srcu, idx);
 	return ret;
 }
@@ -272,8 +272,7 @@ void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
 	srcu_read_unlock(&kvm->irq_srcu, idx);
 }
 
-int kvm_set_routing_entry(struct kvm_irq_routing_table *rt,
-			  struct kvm_kernel_irq_routing_entry *e,
+int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e,
 			  const struct kvm_irq_routing_entry *ue)
 {
 	int r = -EINVAL;
@@ -304,7 +303,6 @@ int kvm_set_routing_entry(struct kvm_irq_routing_table *rt,
 		e->irqchip.pin = ue->u.irqchip.pin + delta;
 		if (e->irqchip.pin >= max_pin)
 			goto out;
-		rt->chip[ue->u.irqchip.irqchip][e->irqchip.pin] = ue->gsi;
 		break;
 	case KVM_IRQ_ROUTING_MSI:
 		e->set = kvm_set_msi;
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
index b43c275..f4648dd 100644
--- a/virt/kvm/irqchip.c
+++ b/virt/kvm/irqchip.c
@@ -31,13 +31,37 @@
 #include <trace/events/kvm.h>
 #include "irq.h"
 
+int kvm_irq_map_gsi(struct kvm_kernel_irq_routing_entry *entries,
+		    struct kvm_irq_routing_table *irq_rt, int gsi)
+{
+	struct kvm_kernel_irq_routing_entry *e;
+	int n = 0;
+
+	if (gsi < irq_rt->nr_rt_entries) {
+		hlist_for_each_entry(e, &irq_rt->map[gsi], link) {
+			entries[n] = *e;
+			++n;
+		}
+	}
+
+	return n;
+}
+
+int kvm_irq_map_chip_pin(struct kvm_irq_routing_table *irq_rt,
+			 unsigned irqchip, unsigned pin)
+{
+	return irq_rt->chip[irqchip][pin];
+}
+
 bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin)
 {
+	struct kvm_irq_routing_table *irq_rt;
 	struct kvm_irq_ack_notifier *kian;
 	int gsi, idx;
 
 	idx = srcu_read_lock(&kvm->irq_srcu);
-	gsi = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu)->chip[irqchip][pin];
+	irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
+	gsi = kvm_irq_map_chip_pin(irq_rt, irqchip, pin);
 	if (gsi != -1)
 		hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
 					 link)
@@ -54,13 +78,15 @@ EXPORT_SYMBOL_GPL(kvm_irq_has_notifier);
 
 void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin)
 {
+	struct kvm_irq_routing_table *irq_rt;
 	struct kvm_irq_ack_notifier *kian;
 	int gsi, idx;
 
 	trace_kvm_ack_irq(irqchip, pin);
 
 	idx = srcu_read_lock(&kvm->irq_srcu);
-	gsi = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu)->chip[irqchip][pin];
+	irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
+	gsi = kvm_irq_map_chip_pin(irq_rt, irqchip, pin);
 	if (gsi != -1)
 		hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
 					 link)
@@ -115,8 +141,8 @@ int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi)
 int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
 		bool line_status)
 {
-	struct kvm_kernel_irq_routing_entry *e, irq_set[KVM_NR_IRQCHIPS];
-	int ret = -1, i = 0, idx;
+	struct kvm_kernel_irq_routing_entry irq_set[KVM_NR_IRQCHIPS];
+	int ret = -1, i, idx;
 	struct kvm_irq_routing_table *irq_rt;
 
 	trace_kvm_set_irq(irq, level, irq_source_id);
@@ -127,9 +153,7 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
 	 */
 	idx = srcu_read_lock(&kvm->irq_srcu);
 	irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
-	if (irq < irq_rt->nr_rt_entries)
-		hlist_for_each_entry(e, &irq_rt->map[irq], link)
-			irq_set[i++] = *e;
+	i = kvm_irq_map_gsi(irq_set, irq_rt, irq);
 	srcu_read_unlock(&kvm->irq_srcu, idx);
 
 	while(i--) {
@@ -171,9 +195,11 @@ static int setup_routing_entry(struct kvm_irq_routing_table *rt,
 
 	e->gsi = ue->gsi;
 	e->type = ue->type;
-	r = kvm_set_routing_entry(rt, e, ue);
+	r = kvm_set_routing_entry(e, ue);
 	if (r)
 		goto out;
+	if (e->type == KVM_IRQ_ROUTING_IRQCHIP)
+		rt->chip[e->irqchip.irqchip][e->irqchip.pin] = e->gsi;
 
 	hlist_add_head(&e->link, &rt->map[e->gsi]);
 	r = 0;
-- 
2.0.0

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 2/6] KVM: irqchip: Provide and use accessors for irq routing table
@ 2014-06-30 10:51   ` Paul Mackerras
  0 siblings, 0 replies; 30+ messages in thread
From: Paul Mackerras @ 2014-06-30 10:51 UTC (permalink / raw)
  To: kvm, kvm-ppc
  Cc: Michael S. Tsirkin, Alexander Graf, Eric Auger, Paul Mackerras

This provides accessor functions for the KVM interrupt mappings, in
order to reduce the amount of code that accesses the fields of the
kvm_irq_routing_table struct, and restrict that code to one file,
virt/kvm/irqchip.c.  The new functions are kvm_irq_map_gsi(), which
maps from a global interrupt number to a set of IRQ routing entries,
and kvm_irq_map_chip_pin, which maps from IRQ chip and pin numbers to
a global interrupt number.

This also moves the update of kvm_irq_routing_table::chip[][]
into irqchip.c, out of the various kvm_set_routing_entry
implementations.  That means that none of the kvm_set_routing_entry
implementations need the kvm_irq_routing_table argument anymore,
so this removes it.

This does not change any locking or data lifetime rules.

Signed-off-by: Paul Mackerras <paulus@samba.org>
---
 arch/powerpc/kvm/mpic.c   |  4 +---
 arch/s390/kvm/interrupt.c |  3 +--
 include/linux/kvm_host.h  |  8 ++++++--
 virt/kvm/eventfd.c        | 10 ++++++----
 virt/kvm/irq_comm.c       | 20 +++++++++-----------
 virt/kvm/irqchip.c        | 42 ++++++++++++++++++++++++++++++++++--------
 6 files changed, 57 insertions(+), 30 deletions(-)

diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c
index b68d0dc..39b3a8f 100644
--- a/arch/powerpc/kvm/mpic.c
+++ b/arch/powerpc/kvm/mpic.c
@@ -1826,8 +1826,7 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
 	return 0;
 }
 
-int kvm_set_routing_entry(struct kvm_irq_routing_table *rt,
-			  struct kvm_kernel_irq_routing_entry *e,
+int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e,
 			  const struct kvm_irq_routing_entry *ue)
 {
 	int r = -EINVAL;
@@ -1839,7 +1838,6 @@ int kvm_set_routing_entry(struct kvm_irq_routing_table *rt,
 		e->irqchip.pin = ue->u.irqchip.pin;
 		if (e->irqchip.pin >= KVM_IRQCHIP_NUM_PINS)
 			goto out;
-		rt->chip[ue->u.irqchip.irqchip][e->irqchip.pin] = ue->gsi;
 		break;
 	case KVM_IRQ_ROUTING_MSI:
 		e->set = kvm_set_msi;
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 90c8de2..cd1e754 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -1589,8 +1589,7 @@ static int set_adapter_int(struct kvm_kernel_irq_routing_entry *e,
 	return ret;
 }
 
-int kvm_set_routing_entry(struct kvm_irq_routing_table *rt,
-			  struct kvm_kernel_irq_routing_entry *e,
+int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e,
 			  const struct kvm_irq_routing_entry *ue)
 {
 	int ret;
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index ec4e3bd..4530753 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -752,6 +752,11 @@ void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
 void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
 			     bool mask);
 
+int kvm_irq_map_gsi(struct kvm_kernel_irq_routing_entry *entries,
+		    struct kvm_irq_routing_table *irq_rt, int gsi);
+int kvm_irq_map_chip_pin(struct kvm_irq_routing_table *irq_rt,
+			 unsigned irqchip, unsigned pin);
+
 int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
 		bool line_status);
 int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level);
@@ -942,8 +947,7 @@ int kvm_set_irq_routing(struct kvm *kvm,
 			const struct kvm_irq_routing_entry *entries,
 			unsigned nr,
 			unsigned flags);
-int kvm_set_routing_entry(struct kvm_irq_routing_table *rt,
-			  struct kvm_kernel_irq_routing_entry *e,
+int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e,
 			  const struct kvm_irq_routing_entry *ue);
 void kvm_free_irq_routing(struct kvm *kvm);
 
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index bae593a..15fa948 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -282,20 +282,22 @@ static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd,
 			 struct kvm_irq_routing_table *irq_rt)
 {
 	struct kvm_kernel_irq_routing_entry *e;
+	struct kvm_kernel_irq_routing_entry entries[KVM_NR_IRQCHIPS];
+	int i, n_entries;
+
+	n_entries = kvm_irq_map_gsi(entries, irq_rt, irqfd->gsi);
 
 	write_seqcount_begin(&irqfd->irq_entry_sc);
 
 	irqfd->irq_entry.type = 0;
-	if (irqfd->gsi >= irq_rt->nr_rt_entries)
-		goto out;
 
-	hlist_for_each_entry(e, &irq_rt->map[irqfd->gsi], link) {
+	e = entries;
+	for (i = 0; i < n_entries; ++i, ++e) {
 		/* Only fast-path MSI. */
 		if (e->type = KVM_IRQ_ROUTING_MSI)
 			irqfd->irq_entry = *e;
 	}
 
- out:
 	write_seqcount_end(&irqfd->irq_entry_sc);
 }
 
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
index ced4a54..6e73af2 100644
--- a/virt/kvm/irq_comm.c
+++ b/virt/kvm/irq_comm.c
@@ -160,6 +160,7 @@ static int kvm_set_msi_inatomic(struct kvm_kernel_irq_routing_entry *e,
  */
 int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level)
 {
+	struct kvm_kernel_irq_routing_entry entries[KVM_NR_IRQCHIPS];
 	struct kvm_kernel_irq_routing_entry *e;
 	int ret = -EINVAL;
 	struct kvm_irq_routing_table *irq_rt;
@@ -177,14 +178,13 @@ int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level)
 	 */
 	idx = srcu_read_lock(&kvm->irq_srcu);
 	irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
-	if (irq < irq_rt->nr_rt_entries)
-		hlist_for_each_entry(e, &irq_rt->map[irq], link) {
-			if (likely(e->type = KVM_IRQ_ROUTING_MSI))
-				ret = kvm_set_msi_inatomic(e, kvm);
-			else
-				ret = -EWOULDBLOCK;
-			break;
-		}
+	if (kvm_irq_map_gsi(entries, irq_rt, irq) > 0) {
+		e = &entries[0];
+		if (likely(e->type = KVM_IRQ_ROUTING_MSI))
+			ret = kvm_set_msi_inatomic(e, kvm);
+		else
+			ret = -EWOULDBLOCK;
+	}
 	srcu_read_unlock(&kvm->irq_srcu, idx);
 	return ret;
 }
@@ -272,8 +272,7 @@ void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
 	srcu_read_unlock(&kvm->irq_srcu, idx);
 }
 
-int kvm_set_routing_entry(struct kvm_irq_routing_table *rt,
-			  struct kvm_kernel_irq_routing_entry *e,
+int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e,
 			  const struct kvm_irq_routing_entry *ue)
 {
 	int r = -EINVAL;
@@ -304,7 +303,6 @@ int kvm_set_routing_entry(struct kvm_irq_routing_table *rt,
 		e->irqchip.pin = ue->u.irqchip.pin + delta;
 		if (e->irqchip.pin >= max_pin)
 			goto out;
-		rt->chip[ue->u.irqchip.irqchip][e->irqchip.pin] = ue->gsi;
 		break;
 	case KVM_IRQ_ROUTING_MSI:
 		e->set = kvm_set_msi;
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
index b43c275..f4648dd 100644
--- a/virt/kvm/irqchip.c
+++ b/virt/kvm/irqchip.c
@@ -31,13 +31,37 @@
 #include <trace/events/kvm.h>
 #include "irq.h"
 
+int kvm_irq_map_gsi(struct kvm_kernel_irq_routing_entry *entries,
+		    struct kvm_irq_routing_table *irq_rt, int gsi)
+{
+	struct kvm_kernel_irq_routing_entry *e;
+	int n = 0;
+
+	if (gsi < irq_rt->nr_rt_entries) {
+		hlist_for_each_entry(e, &irq_rt->map[gsi], link) {
+			entries[n] = *e;
+			++n;
+		}
+	}
+
+	return n;
+}
+
+int kvm_irq_map_chip_pin(struct kvm_irq_routing_table *irq_rt,
+			 unsigned irqchip, unsigned pin)
+{
+	return irq_rt->chip[irqchip][pin];
+}
+
 bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin)
 {
+	struct kvm_irq_routing_table *irq_rt;
 	struct kvm_irq_ack_notifier *kian;
 	int gsi, idx;
 
 	idx = srcu_read_lock(&kvm->irq_srcu);
-	gsi = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu)->chip[irqchip][pin];
+	irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
+	gsi = kvm_irq_map_chip_pin(irq_rt, irqchip, pin);
 	if (gsi != -1)
 		hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
 					 link)
@@ -54,13 +78,15 @@ EXPORT_SYMBOL_GPL(kvm_irq_has_notifier);
 
 void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin)
 {
+	struct kvm_irq_routing_table *irq_rt;
 	struct kvm_irq_ack_notifier *kian;
 	int gsi, idx;
 
 	trace_kvm_ack_irq(irqchip, pin);
 
 	idx = srcu_read_lock(&kvm->irq_srcu);
-	gsi = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu)->chip[irqchip][pin];
+	irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
+	gsi = kvm_irq_map_chip_pin(irq_rt, irqchip, pin);
 	if (gsi != -1)
 		hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
 					 link)
@@ -115,8 +141,8 @@ int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi)
 int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
 		bool line_status)
 {
-	struct kvm_kernel_irq_routing_entry *e, irq_set[KVM_NR_IRQCHIPS];
-	int ret = -1, i = 0, idx;
+	struct kvm_kernel_irq_routing_entry irq_set[KVM_NR_IRQCHIPS];
+	int ret = -1, i, idx;
 	struct kvm_irq_routing_table *irq_rt;
 
 	trace_kvm_set_irq(irq, level, irq_source_id);
@@ -127,9 +153,7 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
 	 */
 	idx = srcu_read_lock(&kvm->irq_srcu);
 	irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
-	if (irq < irq_rt->nr_rt_entries)
-		hlist_for_each_entry(e, &irq_rt->map[irq], link)
-			irq_set[i++] = *e;
+	i = kvm_irq_map_gsi(irq_set, irq_rt, irq);
 	srcu_read_unlock(&kvm->irq_srcu, idx);
 
 	while(i--) {
@@ -171,9 +195,11 @@ static int setup_routing_entry(struct kvm_irq_routing_table *rt,
 
 	e->gsi = ue->gsi;
 	e->type = ue->type;
-	r = kvm_set_routing_entry(rt, e, ue);
+	r = kvm_set_routing_entry(e, ue);
 	if (r)
 		goto out;
+	if (e->type = KVM_IRQ_ROUTING_IRQCHIP)
+		rt->chip[e->irqchip.irqchip][e->irqchip.pin] = e->gsi;
 
 	hlist_add_head(&e->link, &rt->map[e->gsi]);
 	r = 0;
-- 
2.0.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 3/6] KVM: Move all accesses to kvm::irq_routing into irqchip.c
  2014-06-30 10:51 ` Paul Mackerras
@ 2014-06-30 10:51   ` Paul Mackerras
  -1 siblings, 0 replies; 30+ messages in thread
From: Paul Mackerras @ 2014-06-30 10:51 UTC (permalink / raw)
  To: kvm, kvm-ppc
  Cc: Michael S. Tsirkin, Alexander Graf, Eric Auger, Paul Mackerras

Now that struct _irqfd does not keep a reference to storage pointed
to by the irq_routing field of struct kvm, we can move the statement
that updates it out from under the irqfds.lock and put it in
kvm_set_irq_routing() instead.  That means we then have to take a
srcu_read_lock on kvm->irq_srcu around the irqfd_update call in
kvm_irqfd_assign(), since holding the kvm->irqfds.lock no longer
ensures that that the routing can't change.

Combined with changing kvm_irq_map_gsi() and kvm_irq_map_chip_pin()
to take a struct kvm * argument instead of the pointer to the routing
table, this allows us to to move all references to kvm->irq_routing
into irqchip.c.  That in turn allows us to move the definition of the
kvm_irq_routing_table struct into irqchip.c as well.

Signed-off-by: Paul Mackerras <paulus@samba.org>
---
 include/linux/kvm_host.h | 35 +++++++----------------------------
 virt/kvm/eventfd.c       | 22 +++++++++-------------
 virt/kvm/irq_comm.c      |  6 ++----
 virt/kvm/irqchip.c       | 39 +++++++++++++++++++++++++--------------
 4 files changed, 43 insertions(+), 59 deletions(-)

diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 4530753..2346029 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -325,24 +325,7 @@ struct kvm_kernel_irq_routing_entry {
 	struct hlist_node link;
 };
 
-#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
-
-struct kvm_irq_routing_table {
-	int chip[KVM_NR_IRQCHIPS][KVM_IRQCHIP_NUM_PINS];
-	struct kvm_kernel_irq_routing_entry *rt_entries;
-	u32 nr_rt_entries;
-	/*
-	 * Array indexed by gsi. Each entry contains list of irq chips
-	 * the gsi is connected to.
-	 */
-	struct hlist_head map[0];
-};
-
-#else
-
-struct kvm_irq_routing_table {};
-
-#endif
+struct kvm_irq_routing_table;
 
 #ifndef KVM_PRIVATE_MEM_SLOTS
 #define KVM_PRIVATE_MEM_SLOTS 0
@@ -401,8 +384,7 @@ struct kvm {
 	struct mutex irq_lock;
 #ifdef CONFIG_HAVE_KVM_IRQCHIP
 	/*
-	 * Update side is protected by irq_lock and,
-	 * if configured, irqfds.lock.
+	 * Update side is protected by irq_lock.
 	 */
 	struct kvm_irq_routing_table __rcu *irq_routing;
 	struct hlist_head mask_notifier_list;
@@ -752,10 +734,9 @@ void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
 void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
 			     bool mask);
 
-int kvm_irq_map_gsi(struct kvm_kernel_irq_routing_entry *entries,
-		    struct kvm_irq_routing_table *irq_rt, int gsi);
-int kvm_irq_map_chip_pin(struct kvm_irq_routing_table *irq_rt,
-			 unsigned irqchip, unsigned pin);
+int kvm_irq_map_gsi(struct kvm *kvm,
+		    struct kvm_kernel_irq_routing_entry *entries, int gsi);
+int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin);
 
 int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
 		bool line_status);
@@ -967,7 +948,7 @@ int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args);
 #ifdef CONFIG_HAVE_KVM_IRQCHIP
 int kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args);
 void kvm_irqfd_release(struct kvm *kvm);
-void kvm_irq_routing_update(struct kvm *, struct kvm_irq_routing_table *);
+void kvm_irq_routing_update(struct kvm *);
 #else
 static inline int kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args)
 {
@@ -989,10 +970,8 @@ static inline int kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args)
 static inline void kvm_irqfd_release(struct kvm *kvm) {}
 
 #ifdef CONFIG_HAVE_KVM_IRQCHIP
-static inline void kvm_irq_routing_update(struct kvm *kvm,
-					  struct kvm_irq_routing_table *irq_rt)
+static inline void kvm_irq_routing_update(struct kvm *kvm)
 {
-	rcu_assign_pointer(kvm->irq_routing, irq_rt);
 }
 #endif
 
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 15fa948..f0075ff 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -278,14 +278,13 @@ irqfd_ptable_queue_proc(struct file *file, wait_queue_head_t *wqh,
 }
 
 /* Must be called under irqfds.lock */
-static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd,
-			 struct kvm_irq_routing_table *irq_rt)
+static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd)
 {
 	struct kvm_kernel_irq_routing_entry *e;
 	struct kvm_kernel_irq_routing_entry entries[KVM_NR_IRQCHIPS];
 	int i, n_entries;
 
-	n_entries = kvm_irq_map_gsi(entries, irq_rt, irqfd->gsi);
+	n_entries = kvm_irq_map_gsi(kvm, entries, irqfd->gsi);
 
 	write_seqcount_begin(&irqfd->irq_entry_sc);
 
@@ -304,12 +303,12 @@ static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd,
 static int
 kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
 {
-	struct kvm_irq_routing_table *irq_rt;
 	struct _irqfd *irqfd, *tmp;
 	struct fd f;
 	struct eventfd_ctx *eventfd = NULL, *resamplefd = NULL;
 	int ret;
 	unsigned int events;
+	int idx;
 
 	irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL);
 	if (!irqfd)
@@ -403,9 +402,9 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
 		goto fail;
 	}
 
-	irq_rt = rcu_dereference_protected(kvm->irq_routing,
-					   lockdep_is_held(&kvm->irqfds.lock));
-	irqfd_update(kvm, irqfd, irq_rt);
+	idx = srcu_read_lock(&kvm->irq_srcu);
+	irqfd_update(kvm, irqfd);
+	srcu_read_unlock(&kvm->irq_srcu, idx);
 
 	list_add_tail(&irqfd->list, &kvm->irqfds.items);
 
@@ -539,20 +538,17 @@ kvm_irqfd_release(struct kvm *kvm)
 }
 
 /*
- * Change irq_routing and irqfd.
+ * Take note of a change in irq routing.
  * Caller must invoke synchronize_srcu(&kvm->irq_srcu) afterwards.
  */
-void kvm_irq_routing_update(struct kvm *kvm,
-			    struct kvm_irq_routing_table *irq_rt)
+void kvm_irq_routing_update(struct kvm *kvm)
 {
 	struct _irqfd *irqfd;
 
 	spin_lock_irq(&kvm->irqfds.lock);
 
-	rcu_assign_pointer(kvm->irq_routing, irq_rt);
-
 	list_for_each_entry(irqfd, &kvm->irqfds.items, list)
-		irqfd_update(kvm, irqfd, irq_rt);
+		irqfd_update(kvm, irqfd);
 
 	spin_unlock_irq(&kvm->irqfds.lock);
 }
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
index 6e73af2..7f9ad65 100644
--- a/virt/kvm/irq_comm.c
+++ b/virt/kvm/irq_comm.c
@@ -163,7 +163,6 @@ int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level)
 	struct kvm_kernel_irq_routing_entry entries[KVM_NR_IRQCHIPS];
 	struct kvm_kernel_irq_routing_entry *e;
 	int ret = -EINVAL;
-	struct kvm_irq_routing_table *irq_rt;
 	int idx;
 
 	trace_kvm_set_irq(irq, level, irq_source_id);
@@ -177,8 +176,7 @@ int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level)
 	 * which is limited to 1:1 GSI mapping.
 	 */
 	idx = srcu_read_lock(&kvm->irq_srcu);
-	irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
-	if (kvm_irq_map_gsi(entries, irq_rt, irq) > 0) {
+	if (kvm_irq_map_gsi(kvm, entries, irq) > 0) {
 		e = &entries[0];
 		if (likely(e->type == KVM_IRQ_ROUTING_MSI))
 			ret = kvm_set_msi_inatomic(e, kvm);
@@ -264,7 +262,7 @@ void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
 	int idx, gsi;
 
 	idx = srcu_read_lock(&kvm->irq_srcu);
-	gsi = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu)->chip[irqchip][pin];
+	gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
 	if (gsi != -1)
 		hlist_for_each_entry_rcu(kimn, &kvm->mask_notifier_list, link)
 			if (kimn->irq == gsi)
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
index f4648dd..04faac5 100644
--- a/virt/kvm/irqchip.c
+++ b/virt/kvm/irqchip.c
@@ -31,12 +31,26 @@
 #include <trace/events/kvm.h>
 #include "irq.h"
 
-int kvm_irq_map_gsi(struct kvm_kernel_irq_routing_entry *entries,
-		    struct kvm_irq_routing_table *irq_rt, int gsi)
+struct kvm_irq_routing_table {
+	int chip[KVM_NR_IRQCHIPS][KVM_IRQCHIP_NUM_PINS];
+	struct kvm_kernel_irq_routing_entry *rt_entries;
+	u32 nr_rt_entries;
+	/*
+	 * Array indexed by gsi. Each entry contains list of irq chips
+	 * the gsi is connected to.
+	 */
+	struct hlist_head map[0];
+};
+
+int kvm_irq_map_gsi(struct kvm *kvm,
+		    struct kvm_kernel_irq_routing_entry *entries, int gsi)
 {
+	struct kvm_irq_routing_table *irq_rt;
 	struct kvm_kernel_irq_routing_entry *e;
 	int n = 0;
 
+	irq_rt = srcu_dereference_check(kvm->irq_routing, &kvm->irq_srcu,
+					lockdep_is_held(&kvm->irq_lock));
 	if (gsi < irq_rt->nr_rt_entries) {
 		hlist_for_each_entry(e, &irq_rt->map[gsi], link) {
 			entries[n] = *e;
@@ -47,21 +61,21 @@ int kvm_irq_map_gsi(struct kvm_kernel_irq_routing_entry *entries,
 	return n;
 }
 
-int kvm_irq_map_chip_pin(struct kvm_irq_routing_table *irq_rt,
-			 unsigned irqchip, unsigned pin)
+int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin)
 {
+	struct kvm_irq_routing_table *irq_rt;
+
+	irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
 	return irq_rt->chip[irqchip][pin];
 }
 
 bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin)
 {
-	struct kvm_irq_routing_table *irq_rt;
 	struct kvm_irq_ack_notifier *kian;
 	int gsi, idx;
 
 	idx = srcu_read_lock(&kvm->irq_srcu);
-	irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
-	gsi = kvm_irq_map_chip_pin(irq_rt, irqchip, pin);
+	gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
 	if (gsi != -1)
 		hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
 					 link)
@@ -78,15 +92,13 @@ EXPORT_SYMBOL_GPL(kvm_irq_has_notifier);
 
 void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin)
 {
-	struct kvm_irq_routing_table *irq_rt;
 	struct kvm_irq_ack_notifier *kian;
 	int gsi, idx;
 
 	trace_kvm_ack_irq(irqchip, pin);
 
 	idx = srcu_read_lock(&kvm->irq_srcu);
-	irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
-	gsi = kvm_irq_map_chip_pin(irq_rt, irqchip, pin);
+	gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
 	if (gsi != -1)
 		hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
 					 link)
@@ -143,7 +155,6 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
 {
 	struct kvm_kernel_irq_routing_entry irq_set[KVM_NR_IRQCHIPS];
 	int ret = -1, i, idx;
-	struct kvm_irq_routing_table *irq_rt;
 
 	trace_kvm_set_irq(irq, level, irq_source_id);
 
@@ -152,8 +163,7 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
 	 * writes to the unused one.
 	 */
 	idx = srcu_read_lock(&kvm->irq_srcu);
-	irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
-	i = kvm_irq_map_gsi(irq_set, irq_rt, irq);
+	i = kvm_irq_map_gsi(kvm, irq_set, irq);
 	srcu_read_unlock(&kvm->irq_srcu, idx);
 
 	while(i--) {
@@ -250,7 +260,8 @@ int kvm_set_irq_routing(struct kvm *kvm,
 
 	mutex_lock(&kvm->irq_lock);
 	old = kvm->irq_routing;
-	kvm_irq_routing_update(kvm, new);
+	rcu_assign_pointer(kvm->irq_routing, new);
+	kvm_irq_routing_update(kvm);
 	mutex_unlock(&kvm->irq_lock);
 
 	synchronize_srcu_expedited(&kvm->irq_srcu);
-- 
2.0.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 3/6] KVM: Move all accesses to kvm::irq_routing into irqchip.c
@ 2014-06-30 10:51   ` Paul Mackerras
  0 siblings, 0 replies; 30+ messages in thread
From: Paul Mackerras @ 2014-06-30 10:51 UTC (permalink / raw)
  To: kvm, kvm-ppc
  Cc: Michael S. Tsirkin, Alexander Graf, Eric Auger, Paul Mackerras

Now that struct _irqfd does not keep a reference to storage pointed
to by the irq_routing field of struct kvm, we can move the statement
that updates it out from under the irqfds.lock and put it in
kvm_set_irq_routing() instead.  That means we then have to take a
srcu_read_lock on kvm->irq_srcu around the irqfd_update call in
kvm_irqfd_assign(), since holding the kvm->irqfds.lock no longer
ensures that that the routing can't change.

Combined with changing kvm_irq_map_gsi() and kvm_irq_map_chip_pin()
to take a struct kvm * argument instead of the pointer to the routing
table, this allows us to to move all references to kvm->irq_routing
into irqchip.c.  That in turn allows us to move the definition of the
kvm_irq_routing_table struct into irqchip.c as well.

Signed-off-by: Paul Mackerras <paulus@samba.org>
---
 include/linux/kvm_host.h | 35 +++++++----------------------------
 virt/kvm/eventfd.c       | 22 +++++++++-------------
 virt/kvm/irq_comm.c      |  6 ++----
 virt/kvm/irqchip.c       | 39 +++++++++++++++++++++++++--------------
 4 files changed, 43 insertions(+), 59 deletions(-)

diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 4530753..2346029 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -325,24 +325,7 @@ struct kvm_kernel_irq_routing_entry {
 	struct hlist_node link;
 };
 
-#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
-
-struct kvm_irq_routing_table {
-	int chip[KVM_NR_IRQCHIPS][KVM_IRQCHIP_NUM_PINS];
-	struct kvm_kernel_irq_routing_entry *rt_entries;
-	u32 nr_rt_entries;
-	/*
-	 * Array indexed by gsi. Each entry contains list of irq chips
-	 * the gsi is connected to.
-	 */
-	struct hlist_head map[0];
-};
-
-#else
-
-struct kvm_irq_routing_table {};
-
-#endif
+struct kvm_irq_routing_table;
 
 #ifndef KVM_PRIVATE_MEM_SLOTS
 #define KVM_PRIVATE_MEM_SLOTS 0
@@ -401,8 +384,7 @@ struct kvm {
 	struct mutex irq_lock;
 #ifdef CONFIG_HAVE_KVM_IRQCHIP
 	/*
-	 * Update side is protected by irq_lock and,
-	 * if configured, irqfds.lock.
+	 * Update side is protected by irq_lock.
 	 */
 	struct kvm_irq_routing_table __rcu *irq_routing;
 	struct hlist_head mask_notifier_list;
@@ -752,10 +734,9 @@ void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
 void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
 			     bool mask);
 
-int kvm_irq_map_gsi(struct kvm_kernel_irq_routing_entry *entries,
-		    struct kvm_irq_routing_table *irq_rt, int gsi);
-int kvm_irq_map_chip_pin(struct kvm_irq_routing_table *irq_rt,
-			 unsigned irqchip, unsigned pin);
+int kvm_irq_map_gsi(struct kvm *kvm,
+		    struct kvm_kernel_irq_routing_entry *entries, int gsi);
+int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin);
 
 int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
 		bool line_status);
@@ -967,7 +948,7 @@ int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args);
 #ifdef CONFIG_HAVE_KVM_IRQCHIP
 int kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args);
 void kvm_irqfd_release(struct kvm *kvm);
-void kvm_irq_routing_update(struct kvm *, struct kvm_irq_routing_table *);
+void kvm_irq_routing_update(struct kvm *);
 #else
 static inline int kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args)
 {
@@ -989,10 +970,8 @@ static inline int kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args)
 static inline void kvm_irqfd_release(struct kvm *kvm) {}
 
 #ifdef CONFIG_HAVE_KVM_IRQCHIP
-static inline void kvm_irq_routing_update(struct kvm *kvm,
-					  struct kvm_irq_routing_table *irq_rt)
+static inline void kvm_irq_routing_update(struct kvm *kvm)
 {
-	rcu_assign_pointer(kvm->irq_routing, irq_rt);
 }
 #endif
 
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 15fa948..f0075ff 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -278,14 +278,13 @@ irqfd_ptable_queue_proc(struct file *file, wait_queue_head_t *wqh,
 }
 
 /* Must be called under irqfds.lock */
-static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd,
-			 struct kvm_irq_routing_table *irq_rt)
+static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd)
 {
 	struct kvm_kernel_irq_routing_entry *e;
 	struct kvm_kernel_irq_routing_entry entries[KVM_NR_IRQCHIPS];
 	int i, n_entries;
 
-	n_entries = kvm_irq_map_gsi(entries, irq_rt, irqfd->gsi);
+	n_entries = kvm_irq_map_gsi(kvm, entries, irqfd->gsi);
 
 	write_seqcount_begin(&irqfd->irq_entry_sc);
 
@@ -304,12 +303,12 @@ static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd,
 static int
 kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
 {
-	struct kvm_irq_routing_table *irq_rt;
 	struct _irqfd *irqfd, *tmp;
 	struct fd f;
 	struct eventfd_ctx *eventfd = NULL, *resamplefd = NULL;
 	int ret;
 	unsigned int events;
+	int idx;
 
 	irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL);
 	if (!irqfd)
@@ -403,9 +402,9 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
 		goto fail;
 	}
 
-	irq_rt = rcu_dereference_protected(kvm->irq_routing,
-					   lockdep_is_held(&kvm->irqfds.lock));
-	irqfd_update(kvm, irqfd, irq_rt);
+	idx = srcu_read_lock(&kvm->irq_srcu);
+	irqfd_update(kvm, irqfd);
+	srcu_read_unlock(&kvm->irq_srcu, idx);
 
 	list_add_tail(&irqfd->list, &kvm->irqfds.items);
 
@@ -539,20 +538,17 @@ kvm_irqfd_release(struct kvm *kvm)
 }
 
 /*
- * Change irq_routing and irqfd.
+ * Take note of a change in irq routing.
  * Caller must invoke synchronize_srcu(&kvm->irq_srcu) afterwards.
  */
-void kvm_irq_routing_update(struct kvm *kvm,
-			    struct kvm_irq_routing_table *irq_rt)
+void kvm_irq_routing_update(struct kvm *kvm)
 {
 	struct _irqfd *irqfd;
 
 	spin_lock_irq(&kvm->irqfds.lock);
 
-	rcu_assign_pointer(kvm->irq_routing, irq_rt);
-
 	list_for_each_entry(irqfd, &kvm->irqfds.items, list)
-		irqfd_update(kvm, irqfd, irq_rt);
+		irqfd_update(kvm, irqfd);
 
 	spin_unlock_irq(&kvm->irqfds.lock);
 }
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
index 6e73af2..7f9ad65 100644
--- a/virt/kvm/irq_comm.c
+++ b/virt/kvm/irq_comm.c
@@ -163,7 +163,6 @@ int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level)
 	struct kvm_kernel_irq_routing_entry entries[KVM_NR_IRQCHIPS];
 	struct kvm_kernel_irq_routing_entry *e;
 	int ret = -EINVAL;
-	struct kvm_irq_routing_table *irq_rt;
 	int idx;
 
 	trace_kvm_set_irq(irq, level, irq_source_id);
@@ -177,8 +176,7 @@ int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level)
 	 * which is limited to 1:1 GSI mapping.
 	 */
 	idx = srcu_read_lock(&kvm->irq_srcu);
-	irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
-	if (kvm_irq_map_gsi(entries, irq_rt, irq) > 0) {
+	if (kvm_irq_map_gsi(kvm, entries, irq) > 0) {
 		e = &entries[0];
 		if (likely(e->type = KVM_IRQ_ROUTING_MSI))
 			ret = kvm_set_msi_inatomic(e, kvm);
@@ -264,7 +262,7 @@ void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
 	int idx, gsi;
 
 	idx = srcu_read_lock(&kvm->irq_srcu);
-	gsi = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu)->chip[irqchip][pin];
+	gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
 	if (gsi != -1)
 		hlist_for_each_entry_rcu(kimn, &kvm->mask_notifier_list, link)
 			if (kimn->irq = gsi)
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
index f4648dd..04faac5 100644
--- a/virt/kvm/irqchip.c
+++ b/virt/kvm/irqchip.c
@@ -31,12 +31,26 @@
 #include <trace/events/kvm.h>
 #include "irq.h"
 
-int kvm_irq_map_gsi(struct kvm_kernel_irq_routing_entry *entries,
-		    struct kvm_irq_routing_table *irq_rt, int gsi)
+struct kvm_irq_routing_table {
+	int chip[KVM_NR_IRQCHIPS][KVM_IRQCHIP_NUM_PINS];
+	struct kvm_kernel_irq_routing_entry *rt_entries;
+	u32 nr_rt_entries;
+	/*
+	 * Array indexed by gsi. Each entry contains list of irq chips
+	 * the gsi is connected to.
+	 */
+	struct hlist_head map[0];
+};
+
+int kvm_irq_map_gsi(struct kvm *kvm,
+		    struct kvm_kernel_irq_routing_entry *entries, int gsi)
 {
+	struct kvm_irq_routing_table *irq_rt;
 	struct kvm_kernel_irq_routing_entry *e;
 	int n = 0;
 
+	irq_rt = srcu_dereference_check(kvm->irq_routing, &kvm->irq_srcu,
+					lockdep_is_held(&kvm->irq_lock));
 	if (gsi < irq_rt->nr_rt_entries) {
 		hlist_for_each_entry(e, &irq_rt->map[gsi], link) {
 			entries[n] = *e;
@@ -47,21 +61,21 @@ int kvm_irq_map_gsi(struct kvm_kernel_irq_routing_entry *entries,
 	return n;
 }
 
-int kvm_irq_map_chip_pin(struct kvm_irq_routing_table *irq_rt,
-			 unsigned irqchip, unsigned pin)
+int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin)
 {
+	struct kvm_irq_routing_table *irq_rt;
+
+	irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
 	return irq_rt->chip[irqchip][pin];
 }
 
 bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin)
 {
-	struct kvm_irq_routing_table *irq_rt;
 	struct kvm_irq_ack_notifier *kian;
 	int gsi, idx;
 
 	idx = srcu_read_lock(&kvm->irq_srcu);
-	irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
-	gsi = kvm_irq_map_chip_pin(irq_rt, irqchip, pin);
+	gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
 	if (gsi != -1)
 		hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
 					 link)
@@ -78,15 +92,13 @@ EXPORT_SYMBOL_GPL(kvm_irq_has_notifier);
 
 void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin)
 {
-	struct kvm_irq_routing_table *irq_rt;
 	struct kvm_irq_ack_notifier *kian;
 	int gsi, idx;
 
 	trace_kvm_ack_irq(irqchip, pin);
 
 	idx = srcu_read_lock(&kvm->irq_srcu);
-	irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
-	gsi = kvm_irq_map_chip_pin(irq_rt, irqchip, pin);
+	gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
 	if (gsi != -1)
 		hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
 					 link)
@@ -143,7 +155,6 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
 {
 	struct kvm_kernel_irq_routing_entry irq_set[KVM_NR_IRQCHIPS];
 	int ret = -1, i, idx;
-	struct kvm_irq_routing_table *irq_rt;
 
 	trace_kvm_set_irq(irq, level, irq_source_id);
 
@@ -152,8 +163,7 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
 	 * writes to the unused one.
 	 */
 	idx = srcu_read_lock(&kvm->irq_srcu);
-	irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
-	i = kvm_irq_map_gsi(irq_set, irq_rt, irq);
+	i = kvm_irq_map_gsi(kvm, irq_set, irq);
 	srcu_read_unlock(&kvm->irq_srcu, idx);
 
 	while(i--) {
@@ -250,7 +260,8 @@ int kvm_set_irq_routing(struct kvm *kvm,
 
 	mutex_lock(&kvm->irq_lock);
 	old = kvm->irq_routing;
-	kvm_irq_routing_update(kvm, new);
+	rcu_assign_pointer(kvm->irq_routing, new);
+	kvm_irq_routing_update(kvm);
 	mutex_unlock(&kvm->irq_lock);
 
 	synchronize_srcu_expedited(&kvm->irq_srcu);
-- 
2.0.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 4/6] KVM: Move irq notifier implementation into eventfd.c
  2014-06-30 10:51 ` Paul Mackerras
@ 2014-06-30 10:51   ` Paul Mackerras
  -1 siblings, 0 replies; 30+ messages in thread
From: Paul Mackerras @ 2014-06-30 10:51 UTC (permalink / raw)
  To: kvm, kvm-ppc
  Cc: Michael S. Tsirkin, Alexander Graf, Eric Auger, Paul Mackerras

This moves the functions kvm_irq_has_notifier(), kvm_notify_acked_irq(),
kvm_register_irq_ack_notifier() and kvm_unregister_irq_ack_notifier()
from irqchip.c to eventfd.c.  The reason for doing this is that those
functions are used in connection with IRQFDs, which are implemented in
eventfd.c.  In future we will want to use IRQFDs on platforms that
don't implement the GSI routing implemented in irqchip.c, so we won't
be compiling in irqchip.c, but we still need the irq notifiers.  The
implementation is unchanged.

Signed-off-by: Paul Mackerras <paulus@samba.org>
---
 virt/kvm/eventfd.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 virt/kvm/irqchip.c | 61 ----------------------------------------------------
 2 files changed, 63 insertions(+), 61 deletions(-)

diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index f0075ff..99957df 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -34,7 +34,9 @@
 #include <linux/srcu.h>
 #include <linux/slab.h>
 #include <linux/seqlock.h>
+#include <trace/events/kvm.h>
 
+#include "irq.h"
 #include "iodev.h"
 
 #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
@@ -865,3 +867,64 @@ kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
 
 	return kvm_assign_ioeventfd(kvm, args);
 }
+
+bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin)
+{
+	struct kvm_irq_ack_notifier *kian;
+	int gsi, idx;
+
+	idx = srcu_read_lock(&kvm->irq_srcu);
+	gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
+	if (gsi != -1)
+		hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
+					 link)
+			if (kian->gsi == gsi) {
+				srcu_read_unlock(&kvm->irq_srcu, idx);
+				return true;
+			}
+
+	srcu_read_unlock(&kvm->irq_srcu, idx);
+
+	return false;
+}
+EXPORT_SYMBOL_GPL(kvm_irq_has_notifier);
+
+void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin)
+{
+	struct kvm_irq_ack_notifier *kian;
+	int gsi, idx;
+
+	trace_kvm_ack_irq(irqchip, pin);
+
+	idx = srcu_read_lock(&kvm->irq_srcu);
+	gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
+	if (gsi != -1)
+		hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
+					 link)
+			if (kian->gsi == gsi)
+				kian->irq_acked(kian);
+	srcu_read_unlock(&kvm->irq_srcu, idx);
+}
+
+void kvm_register_irq_ack_notifier(struct kvm *kvm,
+				   struct kvm_irq_ack_notifier *kian)
+{
+	mutex_lock(&kvm->irq_lock);
+	hlist_add_head_rcu(&kian->link, &kvm->irq_ack_notifier_list);
+	mutex_unlock(&kvm->irq_lock);
+#ifdef __KVM_HAVE_IOAPIC
+	kvm_vcpu_request_scan_ioapic(kvm);
+#endif
+}
+
+void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
+				    struct kvm_irq_ack_notifier *kian)
+{
+	mutex_lock(&kvm->irq_lock);
+	hlist_del_init_rcu(&kian->link);
+	mutex_unlock(&kvm->irq_lock);
+	synchronize_srcu(&kvm->irq_srcu);
+#ifdef __KVM_HAVE_IOAPIC
+	kvm_vcpu_request_scan_ioapic(kvm);
+#endif
+}
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
index 04faac5..7f256f3 100644
--- a/virt/kvm/irqchip.c
+++ b/virt/kvm/irqchip.c
@@ -69,67 +69,6 @@ int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin)
 	return irq_rt->chip[irqchip][pin];
 }
 
-bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin)
-{
-	struct kvm_irq_ack_notifier *kian;
-	int gsi, idx;
-
-	idx = srcu_read_lock(&kvm->irq_srcu);
-	gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
-	if (gsi != -1)
-		hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
-					 link)
-			if (kian->gsi == gsi) {
-				srcu_read_unlock(&kvm->irq_srcu, idx);
-				return true;
-			}
-
-	srcu_read_unlock(&kvm->irq_srcu, idx);
-
-	return false;
-}
-EXPORT_SYMBOL_GPL(kvm_irq_has_notifier);
-
-void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin)
-{
-	struct kvm_irq_ack_notifier *kian;
-	int gsi, idx;
-
-	trace_kvm_ack_irq(irqchip, pin);
-
-	idx = srcu_read_lock(&kvm->irq_srcu);
-	gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
-	if (gsi != -1)
-		hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
-					 link)
-			if (kian->gsi == gsi)
-				kian->irq_acked(kian);
-	srcu_read_unlock(&kvm->irq_srcu, idx);
-}
-
-void kvm_register_irq_ack_notifier(struct kvm *kvm,
-				   struct kvm_irq_ack_notifier *kian)
-{
-	mutex_lock(&kvm->irq_lock);
-	hlist_add_head_rcu(&kian->link, &kvm->irq_ack_notifier_list);
-	mutex_unlock(&kvm->irq_lock);
-#ifdef __KVM_HAVE_IOAPIC
-	kvm_vcpu_request_scan_ioapic(kvm);
-#endif
-}
-
-void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
-				    struct kvm_irq_ack_notifier *kian)
-{
-	mutex_lock(&kvm->irq_lock);
-	hlist_del_init_rcu(&kian->link);
-	mutex_unlock(&kvm->irq_lock);
-	synchronize_srcu(&kvm->irq_srcu);
-#ifdef __KVM_HAVE_IOAPIC
-	kvm_vcpu_request_scan_ioapic(kvm);
-#endif
-}
-
 int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi)
 {
 	struct kvm_kernel_irq_routing_entry route;
-- 
2.0.0

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 4/6] KVM: Move irq notifier implementation into eventfd.c
@ 2014-06-30 10:51   ` Paul Mackerras
  0 siblings, 0 replies; 30+ messages in thread
From: Paul Mackerras @ 2014-06-30 10:51 UTC (permalink / raw)
  To: kvm, kvm-ppc
  Cc: Michael S. Tsirkin, Alexander Graf, Eric Auger, Paul Mackerras

This moves the functions kvm_irq_has_notifier(), kvm_notify_acked_irq(),
kvm_register_irq_ack_notifier() and kvm_unregister_irq_ack_notifier()
from irqchip.c to eventfd.c.  The reason for doing this is that those
functions are used in connection with IRQFDs, which are implemented in
eventfd.c.  In future we will want to use IRQFDs on platforms that
don't implement the GSI routing implemented in irqchip.c, so we won't
be compiling in irqchip.c, but we still need the irq notifiers.  The
implementation is unchanged.

Signed-off-by: Paul Mackerras <paulus@samba.org>
---
 virt/kvm/eventfd.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 virt/kvm/irqchip.c | 61 ----------------------------------------------------
 2 files changed, 63 insertions(+), 61 deletions(-)

diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index f0075ff..99957df 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -34,7 +34,9 @@
 #include <linux/srcu.h>
 #include <linux/slab.h>
 #include <linux/seqlock.h>
+#include <trace/events/kvm.h>
 
+#include "irq.h"
 #include "iodev.h"
 
 #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
@@ -865,3 +867,64 @@ kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
 
 	return kvm_assign_ioeventfd(kvm, args);
 }
+
+bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin)
+{
+	struct kvm_irq_ack_notifier *kian;
+	int gsi, idx;
+
+	idx = srcu_read_lock(&kvm->irq_srcu);
+	gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
+	if (gsi != -1)
+		hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
+					 link)
+			if (kian->gsi = gsi) {
+				srcu_read_unlock(&kvm->irq_srcu, idx);
+				return true;
+			}
+
+	srcu_read_unlock(&kvm->irq_srcu, idx);
+
+	return false;
+}
+EXPORT_SYMBOL_GPL(kvm_irq_has_notifier);
+
+void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin)
+{
+	struct kvm_irq_ack_notifier *kian;
+	int gsi, idx;
+
+	trace_kvm_ack_irq(irqchip, pin);
+
+	idx = srcu_read_lock(&kvm->irq_srcu);
+	gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
+	if (gsi != -1)
+		hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
+					 link)
+			if (kian->gsi = gsi)
+				kian->irq_acked(kian);
+	srcu_read_unlock(&kvm->irq_srcu, idx);
+}
+
+void kvm_register_irq_ack_notifier(struct kvm *kvm,
+				   struct kvm_irq_ack_notifier *kian)
+{
+	mutex_lock(&kvm->irq_lock);
+	hlist_add_head_rcu(&kian->link, &kvm->irq_ack_notifier_list);
+	mutex_unlock(&kvm->irq_lock);
+#ifdef __KVM_HAVE_IOAPIC
+	kvm_vcpu_request_scan_ioapic(kvm);
+#endif
+}
+
+void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
+				    struct kvm_irq_ack_notifier *kian)
+{
+	mutex_lock(&kvm->irq_lock);
+	hlist_del_init_rcu(&kian->link);
+	mutex_unlock(&kvm->irq_lock);
+	synchronize_srcu(&kvm->irq_srcu);
+#ifdef __KVM_HAVE_IOAPIC
+	kvm_vcpu_request_scan_ioapic(kvm);
+#endif
+}
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
index 04faac5..7f256f3 100644
--- a/virt/kvm/irqchip.c
+++ b/virt/kvm/irqchip.c
@@ -69,67 +69,6 @@ int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin)
 	return irq_rt->chip[irqchip][pin];
 }
 
-bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin)
-{
-	struct kvm_irq_ack_notifier *kian;
-	int gsi, idx;
-
-	idx = srcu_read_lock(&kvm->irq_srcu);
-	gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
-	if (gsi != -1)
-		hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
-					 link)
-			if (kian->gsi = gsi) {
-				srcu_read_unlock(&kvm->irq_srcu, idx);
-				return true;
-			}
-
-	srcu_read_unlock(&kvm->irq_srcu, idx);
-
-	return false;
-}
-EXPORT_SYMBOL_GPL(kvm_irq_has_notifier);
-
-void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin)
-{
-	struct kvm_irq_ack_notifier *kian;
-	int gsi, idx;
-
-	trace_kvm_ack_irq(irqchip, pin);
-
-	idx = srcu_read_lock(&kvm->irq_srcu);
-	gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
-	if (gsi != -1)
-		hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
-					 link)
-			if (kian->gsi = gsi)
-				kian->irq_acked(kian);
-	srcu_read_unlock(&kvm->irq_srcu, idx);
-}
-
-void kvm_register_irq_ack_notifier(struct kvm *kvm,
-				   struct kvm_irq_ack_notifier *kian)
-{
-	mutex_lock(&kvm->irq_lock);
-	hlist_add_head_rcu(&kian->link, &kvm->irq_ack_notifier_list);
-	mutex_unlock(&kvm->irq_lock);
-#ifdef __KVM_HAVE_IOAPIC
-	kvm_vcpu_request_scan_ioapic(kvm);
-#endif
-}
-
-void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
-				    struct kvm_irq_ack_notifier *kian)
-{
-	mutex_lock(&kvm->irq_lock);
-	hlist_del_init_rcu(&kian->link);
-	mutex_unlock(&kvm->irq_lock);
-	synchronize_srcu(&kvm->irq_srcu);
-#ifdef __KVM_HAVE_IOAPIC
-	kvm_vcpu_request_scan_ioapic(kvm);
-#endif
-}
-
 int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi)
 {
 	struct kvm_kernel_irq_routing_entry route;
-- 
2.0.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 5/6] KVM: Give IRQFD its own separate enabling Kconfig option
  2014-06-30 10:51 ` Paul Mackerras
@ 2014-06-30 10:51   ` Paul Mackerras
  -1 siblings, 0 replies; 30+ messages in thread
From: Paul Mackerras @ 2014-06-30 10:51 UTC (permalink / raw)
  To: kvm, kvm-ppc
  Cc: Michael S. Tsirkin, Alexander Graf, Eric Auger, Paul Mackerras

Currently, the IRQFD code is conditional on CONFIG_HAVE_KVM_IRQ_ROUTING.
So that we can have the IRQFD code compiled in without having the
IRQ routing code, this creates a new CONFIG_HAVE_KVM_IRQFD, makes
the IRQFD code conditional on it instead of CONFIG_HAVE_KVM_IRQ_ROUTING,
and makes all the platforms that currently select HAVE_KVM_IRQ_ROUTING
also select HAVE_KVM_IRQFD.

Signed-off-by: Paul Mackerras <paulus@samba.org>
---
 arch/ia64/kvm/Kconfig    | 1 +
 arch/powerpc/kvm/Kconfig | 1 +
 arch/s390/kvm/Kconfig    | 1 +
 arch/x86/kvm/Kconfig     | 1 +
 include/linux/kvm_host.h | 8 ++++----
 virt/kvm/Kconfig         | 3 +++
 virt/kvm/eventfd.c       | 6 +++---
 virt/kvm/kvm_main.c      | 2 +-
 8 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig
index 990b864..3d50ea9 100644
--- a/arch/ia64/kvm/Kconfig
+++ b/arch/ia64/kvm/Kconfig
@@ -25,6 +25,7 @@ config KVM
 	select PREEMPT_NOTIFIERS
 	select ANON_INODES
 	select HAVE_KVM_IRQCHIP
+	select HAVE_KVM_IRQFD
 	select HAVE_KVM_IRQ_ROUTING
 	select KVM_APIC_ARCHITECTURE
 	select KVM_MMIO
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index d6a53b9..e51a140 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -173,6 +173,7 @@ config KVM_MPIC
 	bool "KVM in-kernel MPIC emulation"
 	depends on KVM && E500
 	select HAVE_KVM_IRQCHIP
+	select HAVE_KVM_IRQFD
 	select HAVE_KVM_IRQ_ROUTING
 	select HAVE_KVM_MSI
 	help
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig
index 10d529a..646db9c 100644
--- a/arch/s390/kvm/Kconfig
+++ b/arch/s390/kvm/Kconfig
@@ -26,6 +26,7 @@ config KVM
 	select KVM_ASYNC_PF
 	select KVM_ASYNC_PF_SYNC
 	select HAVE_KVM_IRQCHIP
+	select HAVE_KVM_IRQFD
 	select HAVE_KVM_IRQ_ROUTING
 	---help---
 	  Support hosting paravirtualized guest machines using the SIE
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index 287e4c8..f9d16ff 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -27,6 +27,7 @@ config KVM
 	select MMU_NOTIFIER
 	select ANON_INODES
 	select HAVE_KVM_IRQCHIP
+	select HAVE_KVM_IRQFD
 	select HAVE_KVM_IRQ_ROUTING
 	select HAVE_KVM_EVENTFD
 	select KVM_APIC_ARCHITECTURE
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 2346029..6bbae65 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -437,7 +437,7 @@ void kvm_vcpu_uninit(struct kvm_vcpu *vcpu);
 int __must_check vcpu_load(struct kvm_vcpu *vcpu);
 void vcpu_put(struct kvm_vcpu *vcpu);
 
-#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
+#ifdef CONFIG_HAVE_KVM_IRQFD
 int kvm_irqfd_init(void);
 void kvm_irqfd_exit(void);
 #else
@@ -932,20 +932,20 @@ int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e,
 			  const struct kvm_irq_routing_entry *ue);
 void kvm_free_irq_routing(struct kvm *kvm);
 
-int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi);
-
 #else
 
 static inline void kvm_free_irq_routing(struct kvm *kvm) {}
 
 #endif
 
+int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi);
+
 #ifdef CONFIG_HAVE_KVM_EVENTFD
 
 void kvm_eventfd_init(struct kvm *kvm);
 int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args);
 
-#ifdef CONFIG_HAVE_KVM_IRQCHIP
+#ifdef CONFIG_HAVE_KVM_IRQFD
 int kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args);
 void kvm_irqfd_release(struct kvm *kvm);
 void kvm_irq_routing_update(struct kvm *);
diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig
index 13f2d19..fc0c5e6 100644
--- a/virt/kvm/Kconfig
+++ b/virt/kvm/Kconfig
@@ -6,6 +6,9 @@ config HAVE_KVM
 config HAVE_KVM_IRQCHIP
        bool
 
+config HAVE_KVM_IRQFD
+       bool
+
 config HAVE_KVM_IRQ_ROUTING
        bool
 
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 99957df..f5f6154 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -39,7 +39,7 @@
 #include "irq.h"
 #include "iodev.h"
 
-#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
+#ifdef CONFIG_HAVE_KVM_IRQFD
 /*
  * --------------------------------------------------------------------
  * irqfd: Allows an fd to be used to inject an interrupt to the guest
@@ -450,7 +450,7 @@ out:
 void
 kvm_eventfd_init(struct kvm *kvm)
 {
-#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
+#ifdef CONFIG_HAVE_KVM_IRQFD
 	spin_lock_init(&kvm->irqfds.lock);
 	INIT_LIST_HEAD(&kvm->irqfds.items);
 	INIT_LIST_HEAD(&kvm->irqfds.resampler_list);
@@ -459,7 +459,7 @@ kvm_eventfd_init(struct kvm *kvm)
 	INIT_LIST_HEAD(&kvm->ioeventfds);
 }
 
-#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
+#ifdef CONFIG_HAVE_KVM_IRQFD
 /*
  * shutdown any irqfd's that match fd+gsi
  */
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 4b6c01b..41b8da1 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2584,7 +2584,7 @@ static long kvm_dev_ioctl_check_extension_generic(long arg)
 #ifdef CONFIG_HAVE_KVM_MSI
 	case KVM_CAP_SIGNAL_MSI:
 #endif
-#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
+#ifdef CONFIG_HAVE_KVM_IRQFD
 	case KVM_CAP_IRQFD_RESAMPLE:
 #endif
 		return 1;
-- 
2.0.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 5/6] KVM: Give IRQFD its own separate enabling Kconfig option
@ 2014-06-30 10:51   ` Paul Mackerras
  0 siblings, 0 replies; 30+ messages in thread
From: Paul Mackerras @ 2014-06-30 10:51 UTC (permalink / raw)
  To: kvm, kvm-ppc
  Cc: Michael S. Tsirkin, Alexander Graf, Eric Auger, Paul Mackerras

Currently, the IRQFD code is conditional on CONFIG_HAVE_KVM_IRQ_ROUTING.
So that we can have the IRQFD code compiled in without having the
IRQ routing code, this creates a new CONFIG_HAVE_KVM_IRQFD, makes
the IRQFD code conditional on it instead of CONFIG_HAVE_KVM_IRQ_ROUTING,
and makes all the platforms that currently select HAVE_KVM_IRQ_ROUTING
also select HAVE_KVM_IRQFD.

Signed-off-by: Paul Mackerras <paulus@samba.org>
---
 arch/ia64/kvm/Kconfig    | 1 +
 arch/powerpc/kvm/Kconfig | 1 +
 arch/s390/kvm/Kconfig    | 1 +
 arch/x86/kvm/Kconfig     | 1 +
 include/linux/kvm_host.h | 8 ++++----
 virt/kvm/Kconfig         | 3 +++
 virt/kvm/eventfd.c       | 6 +++---
 virt/kvm/kvm_main.c      | 2 +-
 8 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig
index 990b864..3d50ea9 100644
--- a/arch/ia64/kvm/Kconfig
+++ b/arch/ia64/kvm/Kconfig
@@ -25,6 +25,7 @@ config KVM
 	select PREEMPT_NOTIFIERS
 	select ANON_INODES
 	select HAVE_KVM_IRQCHIP
+	select HAVE_KVM_IRQFD
 	select HAVE_KVM_IRQ_ROUTING
 	select KVM_APIC_ARCHITECTURE
 	select KVM_MMIO
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index d6a53b9..e51a140 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -173,6 +173,7 @@ config KVM_MPIC
 	bool "KVM in-kernel MPIC emulation"
 	depends on KVM && E500
 	select HAVE_KVM_IRQCHIP
+	select HAVE_KVM_IRQFD
 	select HAVE_KVM_IRQ_ROUTING
 	select HAVE_KVM_MSI
 	help
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig
index 10d529a..646db9c 100644
--- a/arch/s390/kvm/Kconfig
+++ b/arch/s390/kvm/Kconfig
@@ -26,6 +26,7 @@ config KVM
 	select KVM_ASYNC_PF
 	select KVM_ASYNC_PF_SYNC
 	select HAVE_KVM_IRQCHIP
+	select HAVE_KVM_IRQFD
 	select HAVE_KVM_IRQ_ROUTING
 	---help---
 	  Support hosting paravirtualized guest machines using the SIE
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index 287e4c8..f9d16ff 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -27,6 +27,7 @@ config KVM
 	select MMU_NOTIFIER
 	select ANON_INODES
 	select HAVE_KVM_IRQCHIP
+	select HAVE_KVM_IRQFD
 	select HAVE_KVM_IRQ_ROUTING
 	select HAVE_KVM_EVENTFD
 	select KVM_APIC_ARCHITECTURE
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 2346029..6bbae65 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -437,7 +437,7 @@ void kvm_vcpu_uninit(struct kvm_vcpu *vcpu);
 int __must_check vcpu_load(struct kvm_vcpu *vcpu);
 void vcpu_put(struct kvm_vcpu *vcpu);
 
-#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
+#ifdef CONFIG_HAVE_KVM_IRQFD
 int kvm_irqfd_init(void);
 void kvm_irqfd_exit(void);
 #else
@@ -932,20 +932,20 @@ int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e,
 			  const struct kvm_irq_routing_entry *ue);
 void kvm_free_irq_routing(struct kvm *kvm);
 
-int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi);
-
 #else
 
 static inline void kvm_free_irq_routing(struct kvm *kvm) {}
 
 #endif
 
+int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi);
+
 #ifdef CONFIG_HAVE_KVM_EVENTFD
 
 void kvm_eventfd_init(struct kvm *kvm);
 int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args);
 
-#ifdef CONFIG_HAVE_KVM_IRQCHIP
+#ifdef CONFIG_HAVE_KVM_IRQFD
 int kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args);
 void kvm_irqfd_release(struct kvm *kvm);
 void kvm_irq_routing_update(struct kvm *);
diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig
index 13f2d19..fc0c5e6 100644
--- a/virt/kvm/Kconfig
+++ b/virt/kvm/Kconfig
@@ -6,6 +6,9 @@ config HAVE_KVM
 config HAVE_KVM_IRQCHIP
        bool
 
+config HAVE_KVM_IRQFD
+       bool
+
 config HAVE_KVM_IRQ_ROUTING
        bool
 
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 99957df..f5f6154 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -39,7 +39,7 @@
 #include "irq.h"
 #include "iodev.h"
 
-#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
+#ifdef CONFIG_HAVE_KVM_IRQFD
 /*
  * --------------------------------------------------------------------
  * irqfd: Allows an fd to be used to inject an interrupt to the guest
@@ -450,7 +450,7 @@ out:
 void
 kvm_eventfd_init(struct kvm *kvm)
 {
-#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
+#ifdef CONFIG_HAVE_KVM_IRQFD
 	spin_lock_init(&kvm->irqfds.lock);
 	INIT_LIST_HEAD(&kvm->irqfds.items);
 	INIT_LIST_HEAD(&kvm->irqfds.resampler_list);
@@ -459,7 +459,7 @@ kvm_eventfd_init(struct kvm *kvm)
 	INIT_LIST_HEAD(&kvm->ioeventfds);
 }
 
-#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
+#ifdef CONFIG_HAVE_KVM_IRQFD
 /*
  * shutdown any irqfd's that match fd+gsi
  */
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 4b6c01b..41b8da1 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2584,7 +2584,7 @@ static long kvm_dev_ioctl_check_extension_generic(long arg)
 #ifdef CONFIG_HAVE_KVM_MSI
 	case KVM_CAP_SIGNAL_MSI:
 #endif
-#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
+#ifdef CONFIG_HAVE_KVM_IRQFD
 	case KVM_CAP_IRQFD_RESAMPLE:
 #endif
 		return 1;
-- 
2.0.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 6/6] KVM: PPC: Enable IRQFD support for the XICS interrupt controller
  2014-06-30 10:51 ` Paul Mackerras
@ 2014-06-30 10:51   ` Paul Mackerras
  -1 siblings, 0 replies; 30+ messages in thread
From: Paul Mackerras @ 2014-06-30 10:51 UTC (permalink / raw)
  To: kvm, kvm-ppc
  Cc: Michael S. Tsirkin, Alexander Graf, Eric Auger, Paul Mackerras

This makes it possible to use IRQFDs on platforms that use the XICS
interrupt controller.  To do this we implement kvm_irq_map_gsi() and
kvm_irq_map_chip_pin() in book3s_xics.c, so as to provide a 1-1 mapping
between global interrupt numbers and XICS interrupt source numbers.
For now, all interrupts are mapped as "IRQCHIP" interrupts, and no
MSI support is provided.

This means that kvm_set_irq can now get called with level == 0 or 1
as well as the powerpc-specific values KVM_INTERRUPT_SET,
KVM_INTERRUPT_UNSET and KVM_INTERRUPT_SET_LEVEL.  We change
ics_deliver_irq() to accept all those values, and remove its
report_status argument, as it is always false, given that we don't
support KVM_IRQ_LINE_STATUS.

This also adds support for interrupt ack notifiers to the XICS code
so that the IRQFD resampler functionality can be supported.

Signed-off-by: Paul Mackerras <paulus@samba.org>
---
 arch/powerpc/kvm/Kconfig             |  2 ++
 arch/powerpc/kvm/book3s_hv_rm_xics.c |  5 ++++
 arch/powerpc/kvm/book3s_xics.c       | 55 ++++++++++++++++++++++++++++++------
 arch/powerpc/kvm/book3s_xics.h       |  2 ++
 4 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index e51a140..296b181 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -185,6 +185,8 @@ config KVM_MPIC
 config KVM_XICS
 	bool "KVM in-kernel XICS emulation"
 	depends on KVM_BOOK3S_64 && !KVM_MPIC
+	select HAVE_KVM_IRQCHIP
+	select HAVE_KVM_IRQFD
 	---help---
 	  Include support for the XICS (eXternal Interrupt Controller
 	  Specification) interrupt controller architecture used on
diff --git a/arch/powerpc/kvm/book3s_hv_rm_xics.c b/arch/powerpc/kvm/book3s_hv_rm_xics.c
index b4b0082..3ee38e6 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_xics.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_xics.c
@@ -401,6 +401,11 @@ int kvmppc_rm_h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr)
 		icp->rm_action |= XICS_RM_REJECT;
 		icp->rm_reject = irq;
 	}
+
+	if (!hlist_empty(&vcpu->kvm->irq_ack_notifier_list)) {
+		icp->rm_action |= XICS_RM_NOTIFY_EOI;
+		icp->rm_eoied_irq = irq;
+	}
  bail:
 	return check_too_hard(xics, icp);
 }
diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c
index d1acd32..eaeb780 100644
--- a/arch/powerpc/kvm/book3s_xics.c
+++ b/arch/powerpc/kvm/book3s_xics.c
@@ -64,8 +64,12 @@
 static void icp_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp,
 			    u32 new_irq);
 
-static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level,
-			   bool report_status)
+/*
+ * Return value ideally indicates how the interrupt was handled, but no
+ * callers look at it (given that we don't implement KVM_IRQ_LINE_STATUS),
+ * so just return 0.
+ */
+static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level)
 {
 	struct ics_irq_state *state;
 	struct kvmppc_ics *ics;
@@ -82,17 +86,14 @@ static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level,
 	if (!state->exists)
 		return -EINVAL;
 
-	if (report_status)
-		return state->asserted;
-
 	/*
 	 * We set state->asserted locklessly. This should be fine as
 	 * we are the only setter, thus concurrent access is undefined
 	 * to begin with.
 	 */
-	if (level == KVM_INTERRUPT_SET_LEVEL)
+	if (level == 1 || level == KVM_INTERRUPT_SET_LEVEL)
 		state->asserted = 1;
-	else if (level == KVM_INTERRUPT_UNSET) {
+	else if (level == 0 || level == KVM_INTERRUPT_UNSET) {
 		state->asserted = 0;
 		return 0;
 	}
@@ -100,7 +101,7 @@ static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level,
 	/* Attempt delivery */
 	icp_deliver_irq(xics, NULL, irq);
 
-	return state->asserted;
+	return 0;
 }
 
 static void ics_check_resend(struct kvmppc_xics *xics, struct kvmppc_ics *ics,
@@ -772,6 +773,8 @@ static noinline int kvmppc_h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr)
 	if (state->asserted)
 		icp_deliver_irq(xics, icp, irq);
 
+	kvm_notify_acked_irq(vcpu->kvm, 0, irq);
+
 	return H_SUCCESS;
 }
 
@@ -789,6 +792,8 @@ static noinline int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall)
 		icp_check_resend(xics, icp);
 	if (icp->rm_action & XICS_RM_REJECT)
 		icp_deliver_irq(xics, icp, icp->rm_reject);
+	if (icp->rm_action & XICS_RM_NOTIFY_EOI)
+		kvm_notify_acked_irq(vcpu->kvm, 0, icp->rm_eoied_irq);
 
 	icp->rm_action = 0;
 
@@ -1170,7 +1175,16 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
 {
 	struct kvmppc_xics *xics = kvm->arch.xics;
 
-	return ics_deliver_irq(xics, irq, level, line_status);
+	return ics_deliver_irq(xics, irq, level);
+}
+
+int kvm_set_msi(struct kvm_kernel_irq_routing_entry *irq_entry, struct kvm *kvm,
+		int irq_source_id, int level, bool line_status)
+{
+	if (!level)
+		return -1;
+	return kvm_set_irq(kvm, irq_source_id, irq_entry->gsi,
+			   level, line_status);
 }
 
 static int xics_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
@@ -1301,3 +1315,26 @@ void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu)
 	vcpu->arch.icp = NULL;
 	vcpu->arch.irq_type = KVMPPC_IRQ_DEFAULT;
 }
+
+static int xics_set_irq(struct kvm_kernel_irq_routing_entry *e,
+			struct kvm *kvm, int irq_source_id, int level,
+			bool line_status)
+{
+	return kvm_set_irq(kvm, irq_source_id, e->gsi, level, line_status);
+}
+
+int kvm_irq_map_gsi(struct kvm *kvm,
+		    struct kvm_kernel_irq_routing_entry *entries, int gsi)
+{
+	entries->gsi = gsi;
+	entries->type = KVM_IRQ_ROUTING_IRQCHIP;
+	entries->set = xics_set_irq;
+	entries->irqchip.irqchip = 0;
+	entries->irqchip.pin = gsi;
+	return 1;
+}
+
+int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin)
+{
+	return pin;
+}
diff --git a/arch/powerpc/kvm/book3s_xics.h b/arch/powerpc/kvm/book3s_xics.h
index dd9326c..e8aaa7a 100644
--- a/arch/powerpc/kvm/book3s_xics.h
+++ b/arch/powerpc/kvm/book3s_xics.h
@@ -71,9 +71,11 @@ struct kvmppc_icp {
 #define XICS_RM_KICK_VCPU	0x1
 #define XICS_RM_CHECK_RESEND	0x2
 #define XICS_RM_REJECT		0x4
+#define XICS_RM_NOTIFY_EOI	0x8
 	u32 rm_action;
 	struct kvm_vcpu *rm_kick_target;
 	u32  rm_reject;
+	u32  rm_eoied_irq;
 
 	/* Debug stuff for real mode */
 	union kvmppc_icp_state rm_dbgstate;
-- 
2.0.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 6/6] KVM: PPC: Enable IRQFD support for the XICS interrupt controller
@ 2014-06-30 10:51   ` Paul Mackerras
  0 siblings, 0 replies; 30+ messages in thread
From: Paul Mackerras @ 2014-06-30 10:51 UTC (permalink / raw)
  To: kvm, kvm-ppc
  Cc: Michael S. Tsirkin, Alexander Graf, Eric Auger, Paul Mackerras

This makes it possible to use IRQFDs on platforms that use the XICS
interrupt controller.  To do this we implement kvm_irq_map_gsi() and
kvm_irq_map_chip_pin() in book3s_xics.c, so as to provide a 1-1 mapping
between global interrupt numbers and XICS interrupt source numbers.
For now, all interrupts are mapped as "IRQCHIP" interrupts, and no
MSI support is provided.

This means that kvm_set_irq can now get called with level = 0 or 1
as well as the powerpc-specific values KVM_INTERRUPT_SET,
KVM_INTERRUPT_UNSET and KVM_INTERRUPT_SET_LEVEL.  We change
ics_deliver_irq() to accept all those values, and remove its
report_status argument, as it is always false, given that we don't
support KVM_IRQ_LINE_STATUS.

This also adds support for interrupt ack notifiers to the XICS code
so that the IRQFD resampler functionality can be supported.

Signed-off-by: Paul Mackerras <paulus@samba.org>
---
 arch/powerpc/kvm/Kconfig             |  2 ++
 arch/powerpc/kvm/book3s_hv_rm_xics.c |  5 ++++
 arch/powerpc/kvm/book3s_xics.c       | 55 ++++++++++++++++++++++++++++++------
 arch/powerpc/kvm/book3s_xics.h       |  2 ++
 4 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index e51a140..296b181 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -185,6 +185,8 @@ config KVM_MPIC
 config KVM_XICS
 	bool "KVM in-kernel XICS emulation"
 	depends on KVM_BOOK3S_64 && !KVM_MPIC
+	select HAVE_KVM_IRQCHIP
+	select HAVE_KVM_IRQFD
 	---help---
 	  Include support for the XICS (eXternal Interrupt Controller
 	  Specification) interrupt controller architecture used on
diff --git a/arch/powerpc/kvm/book3s_hv_rm_xics.c b/arch/powerpc/kvm/book3s_hv_rm_xics.c
index b4b0082..3ee38e6 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_xics.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_xics.c
@@ -401,6 +401,11 @@ int kvmppc_rm_h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr)
 		icp->rm_action |= XICS_RM_REJECT;
 		icp->rm_reject = irq;
 	}
+
+	if (!hlist_empty(&vcpu->kvm->irq_ack_notifier_list)) {
+		icp->rm_action |= XICS_RM_NOTIFY_EOI;
+		icp->rm_eoied_irq = irq;
+	}
  bail:
 	return check_too_hard(xics, icp);
 }
diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c
index d1acd32..eaeb780 100644
--- a/arch/powerpc/kvm/book3s_xics.c
+++ b/arch/powerpc/kvm/book3s_xics.c
@@ -64,8 +64,12 @@
 static void icp_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp,
 			    u32 new_irq);
 
-static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level,
-			   bool report_status)
+/*
+ * Return value ideally indicates how the interrupt was handled, but no
+ * callers look at it (given that we don't implement KVM_IRQ_LINE_STATUS),
+ * so just return 0.
+ */
+static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level)
 {
 	struct ics_irq_state *state;
 	struct kvmppc_ics *ics;
@@ -82,17 +86,14 @@ static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level,
 	if (!state->exists)
 		return -EINVAL;
 
-	if (report_status)
-		return state->asserted;
-
 	/*
 	 * We set state->asserted locklessly. This should be fine as
 	 * we are the only setter, thus concurrent access is undefined
 	 * to begin with.
 	 */
-	if (level = KVM_INTERRUPT_SET_LEVEL)
+	if (level = 1 || level = KVM_INTERRUPT_SET_LEVEL)
 		state->asserted = 1;
-	else if (level = KVM_INTERRUPT_UNSET) {
+	else if (level = 0 || level = KVM_INTERRUPT_UNSET) {
 		state->asserted = 0;
 		return 0;
 	}
@@ -100,7 +101,7 @@ static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level,
 	/* Attempt delivery */
 	icp_deliver_irq(xics, NULL, irq);
 
-	return state->asserted;
+	return 0;
 }
 
 static void ics_check_resend(struct kvmppc_xics *xics, struct kvmppc_ics *ics,
@@ -772,6 +773,8 @@ static noinline int kvmppc_h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr)
 	if (state->asserted)
 		icp_deliver_irq(xics, icp, irq);
 
+	kvm_notify_acked_irq(vcpu->kvm, 0, irq);
+
 	return H_SUCCESS;
 }
 
@@ -789,6 +792,8 @@ static noinline int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall)
 		icp_check_resend(xics, icp);
 	if (icp->rm_action & XICS_RM_REJECT)
 		icp_deliver_irq(xics, icp, icp->rm_reject);
+	if (icp->rm_action & XICS_RM_NOTIFY_EOI)
+		kvm_notify_acked_irq(vcpu->kvm, 0, icp->rm_eoied_irq);
 
 	icp->rm_action = 0;
 
@@ -1170,7 +1175,16 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
 {
 	struct kvmppc_xics *xics = kvm->arch.xics;
 
-	return ics_deliver_irq(xics, irq, level, line_status);
+	return ics_deliver_irq(xics, irq, level);
+}
+
+int kvm_set_msi(struct kvm_kernel_irq_routing_entry *irq_entry, struct kvm *kvm,
+		int irq_source_id, int level, bool line_status)
+{
+	if (!level)
+		return -1;
+	return kvm_set_irq(kvm, irq_source_id, irq_entry->gsi,
+			   level, line_status);
 }
 
 static int xics_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
@@ -1301,3 +1315,26 @@ void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu)
 	vcpu->arch.icp = NULL;
 	vcpu->arch.irq_type = KVMPPC_IRQ_DEFAULT;
 }
+
+static int xics_set_irq(struct kvm_kernel_irq_routing_entry *e,
+			struct kvm *kvm, int irq_source_id, int level,
+			bool line_status)
+{
+	return kvm_set_irq(kvm, irq_source_id, e->gsi, level, line_status);
+}
+
+int kvm_irq_map_gsi(struct kvm *kvm,
+		    struct kvm_kernel_irq_routing_entry *entries, int gsi)
+{
+	entries->gsi = gsi;
+	entries->type = KVM_IRQ_ROUTING_IRQCHIP;
+	entries->set = xics_set_irq;
+	entries->irqchip.irqchip = 0;
+	entries->irqchip.pin = gsi;
+	return 1;
+}
+
+int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin)
+{
+	return pin;
+}
diff --git a/arch/powerpc/kvm/book3s_xics.h b/arch/powerpc/kvm/book3s_xics.h
index dd9326c..e8aaa7a 100644
--- a/arch/powerpc/kvm/book3s_xics.h
+++ b/arch/powerpc/kvm/book3s_xics.h
@@ -71,9 +71,11 @@ struct kvmppc_icp {
 #define XICS_RM_KICK_VCPU	0x1
 #define XICS_RM_CHECK_RESEND	0x2
 #define XICS_RM_REJECT		0x4
+#define XICS_RM_NOTIFY_EOI	0x8
 	u32 rm_action;
 	struct kvm_vcpu *rm_kick_target;
 	u32  rm_reject;
+	u32  rm_eoied_irq;
 
 	/* Debug stuff for real mode */
 	union kvmppc_icp_state rm_dbgstate;
-- 
2.0.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/6] IRQFD without IRQ routing, enabled for XICS
  2014-06-30 10:51 ` Paul Mackerras
@ 2014-06-30 12:43   ` Alexander Graf
  -1 siblings, 0 replies; 30+ messages in thread
From: Alexander Graf @ 2014-06-30 12:43 UTC (permalink / raw)
  To: Paul Mackerras, kvm, kvm-ppc; +Cc: Michael S. Tsirkin, Eric Auger


On 30.06.14 12:51, Paul Mackerras wrote:
> This series of patches provides a way to implement IRQFD support
> without having to implement IRQ routing, and adds IRQFD support for
> the XICS interrupt controller emulation.  (XICS is the interrupt
> controller defined for the pSeries machine type, used on IBM POWER
> servers).
>
> The basic approach is to make it easy for code other than irqchip.c to
> provide a mapping from a global interrupt number (GSI) to an irq
> routing entry (struct kvm_kernel_irq_routing_entry).  To make the
> lifetime of this routing entry easier to manage, we change the IRQFD
> code to keep a copy of the routing entry (for the MSI fast-path case)
> rather than a pointer to the routing entry.  Since the copy can't be
> updated atomically, we add a seqcount_t to make sure that when reading
> it we get a copy that hasn't been half-way updated.
>
> Next we replace the hard-coded accesses outside irqchip.c to the
> fields of the kvm_irq_routing_table struct with calls to accessor
> functions in irqchip.c, namely kvm_irq_map_gsi() and
> kvm_irq_map_chip_pin().  That enables us to move all references to the
> kvm_irq_routing_table struct, and the definition of that struct, into
> irqchip.c.
>
> Then we move the irq notifier implementation from irqchip.c into
> eventfd.c and add a separate Kconfig option to enable IRQFD.  With
> that we can enable IRQFD without irq routing, which we achieve by
> compiling in eventfd.c but not irqchip.c, and providing an alternative
> implementation of kvm_irq_map_gsi() and kvm_irq_map_chip_pin().
>
> The last patch does that for XICS.  With this series I can use
> vhost-net with KVM guests, and I see the TCP bandwidth between guest
> and host on a POWER8 machine go from around 700MB/s to over 2GB/s.
>
> I would like to see this go into 3.17.

I think this approach is good enough for XICS, as it has a 100% flat 
number space. I'm not yet fully convinced how well this would work out 
with the GIC, but I know that one too little to make claims.

The only thing I disliked about this patch set is that it adds another 
piece of code that makes MPIC/XICS exclusive options. But I don't think 
that'd be hard to solve if we start caring.

Overall, nice work.


Alex


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/6] IRQFD without IRQ routing, enabled for XICS
@ 2014-06-30 12:43   ` Alexander Graf
  0 siblings, 0 replies; 30+ messages in thread
From: Alexander Graf @ 2014-06-30 12:43 UTC (permalink / raw)
  To: Paul Mackerras, kvm, kvm-ppc; +Cc: Michael S. Tsirkin, Eric Auger


On 30.06.14 12:51, Paul Mackerras wrote:
> This series of patches provides a way to implement IRQFD support
> without having to implement IRQ routing, and adds IRQFD support for
> the XICS interrupt controller emulation.  (XICS is the interrupt
> controller defined for the pSeries machine type, used on IBM POWER
> servers).
>
> The basic approach is to make it easy for code other than irqchip.c to
> provide a mapping from a global interrupt number (GSI) to an irq
> routing entry (struct kvm_kernel_irq_routing_entry).  To make the
> lifetime of this routing entry easier to manage, we change the IRQFD
> code to keep a copy of the routing entry (for the MSI fast-path case)
> rather than a pointer to the routing entry.  Since the copy can't be
> updated atomically, we add a seqcount_t to make sure that when reading
> it we get a copy that hasn't been half-way updated.
>
> Next we replace the hard-coded accesses outside irqchip.c to the
> fields of the kvm_irq_routing_table struct with calls to accessor
> functions in irqchip.c, namely kvm_irq_map_gsi() and
> kvm_irq_map_chip_pin().  That enables us to move all references to the
> kvm_irq_routing_table struct, and the definition of that struct, into
> irqchip.c.
>
> Then we move the irq notifier implementation from irqchip.c into
> eventfd.c and add a separate Kconfig option to enable IRQFD.  With
> that we can enable IRQFD without irq routing, which we achieve by
> compiling in eventfd.c but not irqchip.c, and providing an alternative
> implementation of kvm_irq_map_gsi() and kvm_irq_map_chip_pin().
>
> The last patch does that for XICS.  With this series I can use
> vhost-net with KVM guests, and I see the TCP bandwidth between guest
> and host on a POWER8 machine go from around 700MB/s to over 2GB/s.
>
> I would like to see this go into 3.17.

I think this approach is good enough for XICS, as it has a 100% flat 
number space. I'm not yet fully convinced how well this would work out 
with the GIC, but I know that one too little to make claims.

The only thing I disliked about this patch set is that it adds another 
piece of code that makes MPIC/XICS exclusive options. But I don't think 
that'd be hard to solve if we start caring.

Overall, nice work.


Alex


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/6] IRQFD without IRQ routing, enabled for XICS
  2014-06-30 12:43   ` Alexander Graf
@ 2014-06-30 21:25     ` Paul Mackerras
  -1 siblings, 0 replies; 30+ messages in thread
From: Paul Mackerras @ 2014-06-30 21:25 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kvm, kvm-ppc, Michael S. Tsirkin, Eric Auger

On Mon, Jun 30, 2014 at 02:43:56PM +0200, Alexander Graf wrote:
> 
> On 30.06.14 12:51, Paul Mackerras wrote:
> >This series of patches provides a way to implement IRQFD support
> >without having to implement IRQ routing, and adds IRQFD support for
> >the XICS interrupt controller emulation.  (XICS is the interrupt
> >controller defined for the pSeries machine type, used on IBM POWER
> >servers).
> >
> >The basic approach is to make it easy for code other than irqchip.c to
> >provide a mapping from a global interrupt number (GSI) to an irq
> >routing entry (struct kvm_kernel_irq_routing_entry).  To make the
> >lifetime of this routing entry easier to manage, we change the IRQFD
> >code to keep a copy of the routing entry (for the MSI fast-path case)
> >rather than a pointer to the routing entry.  Since the copy can't be
> >updated atomically, we add a seqcount_t to make sure that when reading
> >it we get a copy that hasn't been half-way updated.
> >
> >Next we replace the hard-coded accesses outside irqchip.c to the
> >fields of the kvm_irq_routing_table struct with calls to accessor
> >functions in irqchip.c, namely kvm_irq_map_gsi() and
> >kvm_irq_map_chip_pin().  That enables us to move all references to the
> >kvm_irq_routing_table struct, and the definition of that struct, into
> >irqchip.c.
> >
> >Then we move the irq notifier implementation from irqchip.c into
> >eventfd.c and add a separate Kconfig option to enable IRQFD.  With
> >that we can enable IRQFD without irq routing, which we achieve by
> >compiling in eventfd.c but not irqchip.c, and providing an alternative
> >implementation of kvm_irq_map_gsi() and kvm_irq_map_chip_pin().
> >
> >The last patch does that for XICS.  With this series I can use
> >vhost-net with KVM guests, and I see the TCP bandwidth between guest
> >and host on a POWER8 machine go from around 700MB/s to over 2GB/s.
> >
> >I would like to see this go into 3.17.
> 
> I think this approach is good enough for XICS, as it has a 100% flat number
> space. I'm not yet fully convinced how well this would work out with the
> GIC, but I know that one too little to make claims.
> 
> The only thing I disliked about this patch set is that it adds another piece
> of code that makes MPIC/XICS exclusive options. But I don't think that'd be
> hard to solve if we start caring.

I agree.  They were already exclusive, of course, and I just followed
that pattern.  I don't think I made it any harder to change that.

The other thing this patch set does is make it a lot easier to change
the data structures used by the IRQ routing implementation, for
example to use idr structs rather than flat arrays, if we want to,
or to implement range routing entries.

> Overall, nice work.

Thanks.

Paul.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/6] IRQFD without IRQ routing, enabled for XICS
@ 2014-06-30 21:25     ` Paul Mackerras
  0 siblings, 0 replies; 30+ messages in thread
From: Paul Mackerras @ 2014-06-30 21:25 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kvm, kvm-ppc, Michael S. Tsirkin, Eric Auger

On Mon, Jun 30, 2014 at 02:43:56PM +0200, Alexander Graf wrote:
> 
> On 30.06.14 12:51, Paul Mackerras wrote:
> >This series of patches provides a way to implement IRQFD support
> >without having to implement IRQ routing, and adds IRQFD support for
> >the XICS interrupt controller emulation.  (XICS is the interrupt
> >controller defined for the pSeries machine type, used on IBM POWER
> >servers).
> >
> >The basic approach is to make it easy for code other than irqchip.c to
> >provide a mapping from a global interrupt number (GSI) to an irq
> >routing entry (struct kvm_kernel_irq_routing_entry).  To make the
> >lifetime of this routing entry easier to manage, we change the IRQFD
> >code to keep a copy of the routing entry (for the MSI fast-path case)
> >rather than a pointer to the routing entry.  Since the copy can't be
> >updated atomically, we add a seqcount_t to make sure that when reading
> >it we get a copy that hasn't been half-way updated.
> >
> >Next we replace the hard-coded accesses outside irqchip.c to the
> >fields of the kvm_irq_routing_table struct with calls to accessor
> >functions in irqchip.c, namely kvm_irq_map_gsi() and
> >kvm_irq_map_chip_pin().  That enables us to move all references to the
> >kvm_irq_routing_table struct, and the definition of that struct, into
> >irqchip.c.
> >
> >Then we move the irq notifier implementation from irqchip.c into
> >eventfd.c and add a separate Kconfig option to enable IRQFD.  With
> >that we can enable IRQFD without irq routing, which we achieve by
> >compiling in eventfd.c but not irqchip.c, and providing an alternative
> >implementation of kvm_irq_map_gsi() and kvm_irq_map_chip_pin().
> >
> >The last patch does that for XICS.  With this series I can use
> >vhost-net with KVM guests, and I see the TCP bandwidth between guest
> >and host on a POWER8 machine go from around 700MB/s to over 2GB/s.
> >
> >I would like to see this go into 3.17.
> 
> I think this approach is good enough for XICS, as it has a 100% flat number
> space. I'm not yet fully convinced how well this would work out with the
> GIC, but I know that one too little to make claims.
> 
> The only thing I disliked about this patch set is that it adds another piece
> of code that makes MPIC/XICS exclusive options. But I don't think that'd be
> hard to solve if we start caring.

I agree.  They were already exclusive, of course, and I just followed
that pattern.  I don't think I made it any harder to change that.

The other thing this patch set does is make it a lot easier to change
the data structures used by the IRQ routing implementation, for
example to use idr structs rather than flat arrays, if we want to,
or to implement range routing entries.

> Overall, nice work.

Thanks.

Paul.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/6] IRQFD without IRQ routing, enabled for XICS
  2014-06-30 10:51 ` Paul Mackerras
@ 2014-07-13 22:30   ` Paul Mackerras
  -1 siblings, 0 replies; 30+ messages in thread
From: Paul Mackerras @ 2014-07-13 22:30 UTC (permalink / raw)
  To: kvm, kvm-ppc
  Cc: Paolo Bonzini, Michael S. Tsirkin, Alexander Graf, Eric Auger

Ping?

There have been no comments on this patch series in two weeks, except
for Alex's comment that was mostly positive.  Could someone put it
into the kvm tree please?

Thanks,
Paul.

On Mon, Jun 30, 2014 at 08:51:08PM +1000, Paul Mackerras wrote:
> This series of patches provides a way to implement IRQFD support
> without having to implement IRQ routing, and adds IRQFD support for
> the XICS interrupt controller emulation.  (XICS is the interrupt
> controller defined for the pSeries machine type, used on IBM POWER
> servers).
> 
> The basic approach is to make it easy for code other than irqchip.c to
> provide a mapping from a global interrupt number (GSI) to an irq
> routing entry (struct kvm_kernel_irq_routing_entry).  To make the
> lifetime of this routing entry easier to manage, we change the IRQFD
> code to keep a copy of the routing entry (for the MSI fast-path case)
> rather than a pointer to the routing entry.  Since the copy can't be
> updated atomically, we add a seqcount_t to make sure that when reading
> it we get a copy that hasn't been half-way updated.
> 
> Next we replace the hard-coded accesses outside irqchip.c to the
> fields of the kvm_irq_routing_table struct with calls to accessor
> functions in irqchip.c, namely kvm_irq_map_gsi() and
> kvm_irq_map_chip_pin().  That enables us to move all references to the
> kvm_irq_routing_table struct, and the definition of that struct, into
> irqchip.c.
> 
> Then we move the irq notifier implementation from irqchip.c into
> eventfd.c and add a separate Kconfig option to enable IRQFD.  With
> that we can enable IRQFD without irq routing, which we achieve by
> compiling in eventfd.c but not irqchip.c, and providing an alternative
> implementation of kvm_irq_map_gsi() and kvm_irq_map_chip_pin().
> 
> The last patch does that for XICS.  With this series I can use
> vhost-net with KVM guests, and I see the TCP bandwidth between guest
> and host on a POWER8 machine go from around 700MB/s to over 2GB/s.
> 
> I would like to see this go into 3.17.
> 
>  arch/ia64/kvm/Kconfig                |   1 +
>  arch/powerpc/kvm/Kconfig             |   3 +
>  arch/powerpc/kvm/book3s_hv_rm_xics.c |   5 ++
>  arch/powerpc/kvm/book3s_xics.c       |  55 +++++++++++---
>  arch/powerpc/kvm/book3s_xics.h       |   2 +
>  arch/powerpc/kvm/mpic.c              |   4 +-
>  arch/s390/kvm/Kconfig                |   1 +
>  arch/s390/kvm/interrupt.c            |   3 +-
>  arch/x86/kvm/Kconfig                 |   1 +
>  include/linux/kvm_host.h             |  43 ++++-------
>  virt/kvm/Kconfig                     |   3 +
>  virt/kvm/eventfd.c                   | 134 ++++++++++++++++++++++++++---------
>  virt/kvm/irq_comm.c                  |  24 +++----
>  virt/kvm/irqchip.c                   |  98 ++++++++++---------------
>  virt/kvm/kvm_main.c                  |   2 +-
>  15 files changed, 227 insertions(+), 152 deletions(-)
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/6] IRQFD without IRQ routing, enabled for XICS
@ 2014-07-13 22:30   ` Paul Mackerras
  0 siblings, 0 replies; 30+ messages in thread
From: Paul Mackerras @ 2014-07-13 22:30 UTC (permalink / raw)
  To: kvm, kvm-ppc
  Cc: Paolo Bonzini, Michael S. Tsirkin, Alexander Graf, Eric Auger

Ping?

There have been no comments on this patch series in two weeks, except
for Alex's comment that was mostly positive.  Could someone put it
into the kvm tree please?

Thanks,
Paul.

On Mon, Jun 30, 2014 at 08:51:08PM +1000, Paul Mackerras wrote:
> This series of patches provides a way to implement IRQFD support
> without having to implement IRQ routing, and adds IRQFD support for
> the XICS interrupt controller emulation.  (XICS is the interrupt
> controller defined for the pSeries machine type, used on IBM POWER
> servers).
> 
> The basic approach is to make it easy for code other than irqchip.c to
> provide a mapping from a global interrupt number (GSI) to an irq
> routing entry (struct kvm_kernel_irq_routing_entry).  To make the
> lifetime of this routing entry easier to manage, we change the IRQFD
> code to keep a copy of the routing entry (for the MSI fast-path case)
> rather than a pointer to the routing entry.  Since the copy can't be
> updated atomically, we add a seqcount_t to make sure that when reading
> it we get a copy that hasn't been half-way updated.
> 
> Next we replace the hard-coded accesses outside irqchip.c to the
> fields of the kvm_irq_routing_table struct with calls to accessor
> functions in irqchip.c, namely kvm_irq_map_gsi() and
> kvm_irq_map_chip_pin().  That enables us to move all references to the
> kvm_irq_routing_table struct, and the definition of that struct, into
> irqchip.c.
> 
> Then we move the irq notifier implementation from irqchip.c into
> eventfd.c and add a separate Kconfig option to enable IRQFD.  With
> that we can enable IRQFD without irq routing, which we achieve by
> compiling in eventfd.c but not irqchip.c, and providing an alternative
> implementation of kvm_irq_map_gsi() and kvm_irq_map_chip_pin().
> 
> The last patch does that for XICS.  With this series I can use
> vhost-net with KVM guests, and I see the TCP bandwidth between guest
> and host on a POWER8 machine go from around 700MB/s to over 2GB/s.
> 
> I would like to see this go into 3.17.
> 
>  arch/ia64/kvm/Kconfig                |   1 +
>  arch/powerpc/kvm/Kconfig             |   3 +
>  arch/powerpc/kvm/book3s_hv_rm_xics.c |   5 ++
>  arch/powerpc/kvm/book3s_xics.c       |  55 +++++++++++---
>  arch/powerpc/kvm/book3s_xics.h       |   2 +
>  arch/powerpc/kvm/mpic.c              |   4 +-
>  arch/s390/kvm/Kconfig                |   1 +
>  arch/s390/kvm/interrupt.c            |   3 +-
>  arch/x86/kvm/Kconfig                 |   1 +
>  include/linux/kvm_host.h             |  43 ++++-------
>  virt/kvm/Kconfig                     |   3 +
>  virt/kvm/eventfd.c                   | 134 ++++++++++++++++++++++++++---------
>  virt/kvm/irq_comm.c                  |  24 +++----
>  virt/kvm/irqchip.c                   |  98 ++++++++++---------------
>  virt/kvm/kvm_main.c                  |   2 +-
>  15 files changed, 227 insertions(+), 152 deletions(-)
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/6] IRQFD without IRQ routing, enabled for XICS
  2014-06-30 10:51 ` Paul Mackerras
@ 2014-07-14 14:18   ` Cornelia Huck
  -1 siblings, 0 replies; 30+ messages in thread
From: Cornelia Huck @ 2014-07-14 14:18 UTC (permalink / raw)
  To: Paul Mackerras
  Cc: kvm, kvm-ppc, Michael S. Tsirkin, Alexander Graf, Eric Auger

On Mon, 30 Jun 2014 20:51:08 +1000
Paul Mackerras <paulus@samba.org> wrote:

> I would like to see this go into 3.17.

FWIW: I've given this a whirl on s390 (with a dataplane disk), and
everything seems to work as before.

The only thing which is I think worth mentioning is that embedding the
routing entry into the irqfd struct will grow it a bit, which might be
noticable on large installations with hundreds of devices. OTOH, the
routing entry isn't too large, so I don't think it will become a
problem.

> 
>  arch/ia64/kvm/Kconfig                |   1 +
>  arch/powerpc/kvm/Kconfig             |   3 +
>  arch/powerpc/kvm/book3s_hv_rm_xics.c |   5 ++
>  arch/powerpc/kvm/book3s_xics.c       |  55 +++++++++++---
>  arch/powerpc/kvm/book3s_xics.h       |   2 +
>  arch/powerpc/kvm/mpic.c              |   4 +-
>  arch/s390/kvm/Kconfig                |   1 +
>  arch/s390/kvm/interrupt.c            |   3 +-
>  arch/x86/kvm/Kconfig                 |   1 +
>  include/linux/kvm_host.h             |  43 ++++-------
>  virt/kvm/Kconfig                     |   3 +
>  virt/kvm/eventfd.c                   | 134 ++++++++++++++++++++++++++---------
>  virt/kvm/irq_comm.c                  |  24 +++----
>  virt/kvm/irqchip.c                   |  98 ++++++++++---------------
>  virt/kvm/kvm_main.c                  |   2 +-
>  15 files changed, 227 insertions(+), 152 deletions(-)


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/6] IRQFD without IRQ routing, enabled for XICS
@ 2014-07-14 14:18   ` Cornelia Huck
  0 siblings, 0 replies; 30+ messages in thread
From: Cornelia Huck @ 2014-07-14 14:18 UTC (permalink / raw)
  To: Paul Mackerras
  Cc: kvm, kvm-ppc, Michael S. Tsirkin, Alexander Graf, Eric Auger

On Mon, 30 Jun 2014 20:51:08 +1000
Paul Mackerras <paulus@samba.org> wrote:

> I would like to see this go into 3.17.

FWIW: I've given this a whirl on s390 (with a dataplane disk), and
everything seems to work as before.

The only thing which is I think worth mentioning is that embedding the
routing entry into the irqfd struct will grow it a bit, which might be
noticable on large installations with hundreds of devices. OTOH, the
routing entry isn't too large, so I don't think it will become a
problem.

> 
>  arch/ia64/kvm/Kconfig                |   1 +
>  arch/powerpc/kvm/Kconfig             |   3 +
>  arch/powerpc/kvm/book3s_hv_rm_xics.c |   5 ++
>  arch/powerpc/kvm/book3s_xics.c       |  55 +++++++++++---
>  arch/powerpc/kvm/book3s_xics.h       |   2 +
>  arch/powerpc/kvm/mpic.c              |   4 +-
>  arch/s390/kvm/Kconfig                |   1 +
>  arch/s390/kvm/interrupt.c            |   3 +-
>  arch/x86/kvm/Kconfig                 |   1 +
>  include/linux/kvm_host.h             |  43 ++++-------
>  virt/kvm/Kconfig                     |   3 +
>  virt/kvm/eventfd.c                   | 134 ++++++++++++++++++++++++++---------
>  virt/kvm/irq_comm.c                  |  24 +++----
>  virt/kvm/irqchip.c                   |  98 ++++++++++---------------
>  virt/kvm/kvm_main.c                  |   2 +-
>  15 files changed, 227 insertions(+), 152 deletions(-)


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/6] IRQFD without IRQ routing, enabled for XICS
  2014-07-14 14:18   ` Cornelia Huck
@ 2014-07-24 15:47     ` Eric Auger
  -1 siblings, 0 replies; 30+ messages in thread
From: Eric Auger @ 2014-07-24 15:47 UTC (permalink / raw)
  To: Cornelia Huck, Paul Mackerras
  Cc: kvm, kvm-ppc, Michael S. Tsirkin, Alexander Graf

Hi Paul,

I also confirm your patch works fine on my ARM test environment. I was
able to run
- with irqchip without regression
- without irqchip (ie removing routing totally), just implementing
identity kvm_irq_map_gsi and kvm_irq_map_chip_pin and proper
kvm_set_irq. The overall integration becomes much simpler :-)

Many thanks

Best Regards

Eric

 On 07/14/2014 04:18 PM, Cornelia Huck wrote:
> On Mon, 30 Jun 2014 20:51:08 +1000
> Paul Mackerras <paulus@samba.org> wrote:
> 
>> I would like to see this go into 3.17.
> 
> FWIW: I've given this a whirl on s390 (with a dataplane disk), and
> everything seems to work as before.
> 
> The only thing which is I think worth mentioning is that embedding the
> routing entry into the irqfd struct will grow it a bit, which might be
> noticable on large installations with hundreds of devices. OTOH, the
> routing entry isn't too large, so I don't think it will become a
> problem.
> 
>>
>>  arch/ia64/kvm/Kconfig                |   1 +
>>  arch/powerpc/kvm/Kconfig             |   3 +
>>  arch/powerpc/kvm/book3s_hv_rm_xics.c |   5 ++
>>  arch/powerpc/kvm/book3s_xics.c       |  55 +++++++++++---
>>  arch/powerpc/kvm/book3s_xics.h       |   2 +
>>  arch/powerpc/kvm/mpic.c              |   4 +-
>>  arch/s390/kvm/Kconfig                |   1 +
>>  arch/s390/kvm/interrupt.c            |   3 +-
>>  arch/x86/kvm/Kconfig                 |   1 +
>>  include/linux/kvm_host.h             |  43 ++++-------
>>  virt/kvm/Kconfig                     |   3 +
>>  virt/kvm/eventfd.c                   | 134 ++++++++++++++++++++++++++---------
>>  virt/kvm/irq_comm.c                  |  24 +++----
>>  virt/kvm/irqchip.c                   |  98 ++++++++++---------------
>>  virt/kvm/kvm_main.c                  |   2 +-
>>  15 files changed, 227 insertions(+), 152 deletions(-)
> 

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/6] IRQFD without IRQ routing, enabled for XICS
@ 2014-07-24 15:47     ` Eric Auger
  0 siblings, 0 replies; 30+ messages in thread
From: Eric Auger @ 2014-07-24 15:47 UTC (permalink / raw)
  To: Cornelia Huck, Paul Mackerras
  Cc: kvm, kvm-ppc, Michael S. Tsirkin, Alexander Graf

Hi Paul,

I also confirm your patch works fine on my ARM test environment. I was
able to run
- with irqchip without regression
- without irqchip (ie removing routing totally), just implementing
identity kvm_irq_map_gsi and kvm_irq_map_chip_pin and proper
kvm_set_irq. The overall integration becomes much simpler :-)

Many thanks

Best Regards

Eric

 On 07/14/2014 04:18 PM, Cornelia Huck wrote:
> On Mon, 30 Jun 2014 20:51:08 +1000
> Paul Mackerras <paulus@samba.org> wrote:
> 
>> I would like to see this go into 3.17.
> 
> FWIW: I've given this a whirl on s390 (with a dataplane disk), and
> everything seems to work as before.
> 
> The only thing which is I think worth mentioning is that embedding the
> routing entry into the irqfd struct will grow it a bit, which might be
> noticable on large installations with hundreds of devices. OTOH, the
> routing entry isn't too large, so I don't think it will become a
> problem.
> 
>>
>>  arch/ia64/kvm/Kconfig                |   1 +
>>  arch/powerpc/kvm/Kconfig             |   3 +
>>  arch/powerpc/kvm/book3s_hv_rm_xics.c |   5 ++
>>  arch/powerpc/kvm/book3s_xics.c       |  55 +++++++++++---
>>  arch/powerpc/kvm/book3s_xics.h       |   2 +
>>  arch/powerpc/kvm/mpic.c              |   4 +-
>>  arch/s390/kvm/Kconfig                |   1 +
>>  arch/s390/kvm/interrupt.c            |   3 +-
>>  arch/x86/kvm/Kconfig                 |   1 +
>>  include/linux/kvm_host.h             |  43 ++++-------
>>  virt/kvm/Kconfig                     |   3 +
>>  virt/kvm/eventfd.c                   | 134 ++++++++++++++++++++++++++---------
>>  virt/kvm/irq_comm.c                  |  24 +++----
>>  virt/kvm/irqchip.c                   |  98 ++++++++++---------------
>>  virt/kvm/kvm_main.c                  |   2 +-
>>  15 files changed, 227 insertions(+), 152 deletions(-)
> 


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/6] IRQFD without IRQ routing, enabled for XICS
  2014-06-30 10:51 ` Paul Mackerras
@ 2014-08-05 12:27   ` Paolo Bonzini
  -1 siblings, 0 replies; 30+ messages in thread
From: Paolo Bonzini @ 2014-08-05 12:27 UTC (permalink / raw)
  To: Paul Mackerras, kvm, kvm-ppc
  Cc: Michael S. Tsirkin, Alexander Graf, Eric Auger

Il 30/06/2014 12:51, Paul Mackerras ha scritto:
> This series of patches provides a way to implement IRQFD support
> without having to implement IRQ routing, and adds IRQFD support for
> the XICS interrupt controller emulation.  (XICS is the interrupt
> controller defined for the pSeries machine type, used on IBM POWER
> servers).
> 
> The basic approach is to make it easy for code other than irqchip.c to
> provide a mapping from a global interrupt number (GSI) to an irq
> routing entry (struct kvm_kernel_irq_routing_entry).  To make the
> lifetime of this routing entry easier to manage, we change the IRQFD
> code to keep a copy of the routing entry (for the MSI fast-path case)
> rather than a pointer to the routing entry.  Since the copy can't be
> updated atomically, we add a seqcount_t to make sure that when reading
> it we get a copy that hasn't been half-way updated.
> 
> Next we replace the hard-coded accesses outside irqchip.c to the
> fields of the kvm_irq_routing_table struct with calls to accessor
> functions in irqchip.c, namely kvm_irq_map_gsi() and
> kvm_irq_map_chip_pin().  That enables us to move all references to the
> kvm_irq_routing_table struct, and the definition of that struct, into
> irqchip.c.
> 
> Then we move the irq notifier implementation from irqchip.c into
> eventfd.c and add a separate Kconfig option to enable IRQFD.  With
> that we can enable IRQFD without irq routing, which we achieve by
> compiling in eventfd.c but not irqchip.c, and providing an alternative
> implementation of kvm_irq_map_gsi() and kvm_irq_map_chip_pin().
> 
> The last patch does that for XICS.  With this series I can use
> vhost-net with KVM guests, and I see the TCP bandwidth between guest
> and host on a POWER8 machine go from around 700MB/s to over 2GB/s.
> 
> I would like to see this go into 3.17.
> 
>  arch/ia64/kvm/Kconfig                |   1 +
>  arch/powerpc/kvm/Kconfig             |   3 +
>  arch/powerpc/kvm/book3s_hv_rm_xics.c |   5 ++
>  arch/powerpc/kvm/book3s_xics.c       |  55 +++++++++++---
>  arch/powerpc/kvm/book3s_xics.h       |   2 +
>  arch/powerpc/kvm/mpic.c              |   4 +-
>  arch/s390/kvm/Kconfig                |   1 +
>  arch/s390/kvm/interrupt.c            |   3 +-
>  arch/x86/kvm/Kconfig                 |   1 +
>  include/linux/kvm_host.h             |  43 ++++-------
>  virt/kvm/Kconfig                     |   3 +
>  virt/kvm/eventfd.c                   | 134 ++++++++++++++++++++++++++---------
>  virt/kvm/irq_comm.c                  |  24 +++----
>  virt/kvm/irqchip.c                   |  98 ++++++++++---------------
>  virt/kvm/kvm_main.c                  |   2 +-
>  15 files changed, 227 insertions(+), 152 deletions(-)
> 

Applied for 3.17, thanks Eric and Cornelia for testing.

Paolo

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/6] IRQFD without IRQ routing, enabled for XICS
@ 2014-08-05 12:27   ` Paolo Bonzini
  0 siblings, 0 replies; 30+ messages in thread
From: Paolo Bonzini @ 2014-08-05 12:27 UTC (permalink / raw)
  To: Paul Mackerras, kvm, kvm-ppc
  Cc: Michael S. Tsirkin, Alexander Graf, Eric Auger

Il 30/06/2014 12:51, Paul Mackerras ha scritto:
> This series of patches provides a way to implement IRQFD support
> without having to implement IRQ routing, and adds IRQFD support for
> the XICS interrupt controller emulation.  (XICS is the interrupt
> controller defined for the pSeries machine type, used on IBM POWER
> servers).
> 
> The basic approach is to make it easy for code other than irqchip.c to
> provide a mapping from a global interrupt number (GSI) to an irq
> routing entry (struct kvm_kernel_irq_routing_entry).  To make the
> lifetime of this routing entry easier to manage, we change the IRQFD
> code to keep a copy of the routing entry (for the MSI fast-path case)
> rather than a pointer to the routing entry.  Since the copy can't be
> updated atomically, we add a seqcount_t to make sure that when reading
> it we get a copy that hasn't been half-way updated.
> 
> Next we replace the hard-coded accesses outside irqchip.c to the
> fields of the kvm_irq_routing_table struct with calls to accessor
> functions in irqchip.c, namely kvm_irq_map_gsi() and
> kvm_irq_map_chip_pin().  That enables us to move all references to the
> kvm_irq_routing_table struct, and the definition of that struct, into
> irqchip.c.
> 
> Then we move the irq notifier implementation from irqchip.c into
> eventfd.c and add a separate Kconfig option to enable IRQFD.  With
> that we can enable IRQFD without irq routing, which we achieve by
> compiling in eventfd.c but not irqchip.c, and providing an alternative
> implementation of kvm_irq_map_gsi() and kvm_irq_map_chip_pin().
> 
> The last patch does that for XICS.  With this series I can use
> vhost-net with KVM guests, and I see the TCP bandwidth between guest
> and host on a POWER8 machine go from around 700MB/s to over 2GB/s.
> 
> I would like to see this go into 3.17.
> 
>  arch/ia64/kvm/Kconfig                |   1 +
>  arch/powerpc/kvm/Kconfig             |   3 +
>  arch/powerpc/kvm/book3s_hv_rm_xics.c |   5 ++
>  arch/powerpc/kvm/book3s_xics.c       |  55 +++++++++++---
>  arch/powerpc/kvm/book3s_xics.h       |   2 +
>  arch/powerpc/kvm/mpic.c              |   4 +-
>  arch/s390/kvm/Kconfig                |   1 +
>  arch/s390/kvm/interrupt.c            |   3 +-
>  arch/x86/kvm/Kconfig                 |   1 +
>  include/linux/kvm_host.h             |  43 ++++-------
>  virt/kvm/Kconfig                     |   3 +
>  virt/kvm/eventfd.c                   | 134 ++++++++++++++++++++++++++---------
>  virt/kvm/irq_comm.c                  |  24 +++----
>  virt/kvm/irqchip.c                   |  98 ++++++++++---------------
>  virt/kvm/kvm_main.c                  |   2 +-
>  15 files changed, 227 insertions(+), 152 deletions(-)
> 

Applied for 3.17, thanks Eric and Cornelia for testing.

Paolo

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/6] IRQFD without IRQ routing, enabled for XICS
  2014-08-05 12:27   ` Paolo Bonzini
@ 2014-08-06 12:35     ` Paolo Bonzini
  -1 siblings, 0 replies; 30+ messages in thread
From: Paolo Bonzini @ 2014-08-06 12:35 UTC (permalink / raw)
  To: Paul Mackerras, kvm, kvm-ppc
  Cc: Michael S. Tsirkin, Alexander Graf, Eric Auger

Il 05/08/2014 14:27, Paolo Bonzini ha scritto:
> Il 30/06/2014 12:51, Paul Mackerras ha scritto:
>> This series of patches provides a way to implement IRQFD support
>> without having to implement IRQ routing, and adds IRQFD support for
>> the XICS interrupt controller emulation.  (XICS is the interrupt
>> controller defined for the pSeries machine type, used on IBM POWER
>> servers).
>>
>> The basic approach is to make it easy for code other than irqchip.c to
>> provide a mapping from a global interrupt number (GSI) to an irq
>> routing entry (struct kvm_kernel_irq_routing_entry).  To make the
>> lifetime of this routing entry easier to manage, we change the IRQFD
>> code to keep a copy of the routing entry (for the MSI fast-path case)
>> rather than a pointer to the routing entry.  Since the copy can't be
>> updated atomically, we add a seqcount_t to make sure that when reading
>> it we get a copy that hasn't been half-way updated.
>>
>> Next we replace the hard-coded accesses outside irqchip.c to the
>> fields of the kvm_irq_routing_table struct with calls to accessor
>> functions in irqchip.c, namely kvm_irq_map_gsi() and
>> kvm_irq_map_chip_pin().  That enables us to move all references to the
>> kvm_irq_routing_table struct, and the definition of that struct, into
>> irqchip.c.
>>
>> Then we move the irq notifier implementation from irqchip.c into
>> eventfd.c and add a separate Kconfig option to enable IRQFD.  With
>> that we can enable IRQFD without irq routing, which we achieve by
>> compiling in eventfd.c but not irqchip.c, and providing an alternative
>> implementation of kvm_irq_map_gsi() and kvm_irq_map_chip_pin().
>>
>> The last patch does that for XICS.  With this series I can use
>> vhost-net with KVM guests, and I see the TCP bandwidth between guest
>> and host on a POWER8 machine go from around 700MB/s to over 2GB/s.
>>
>> I would like to see this go into 3.17.
>>
>>  arch/ia64/kvm/Kconfig                |   1 +
>>  arch/powerpc/kvm/Kconfig             |   3 +
>>  arch/powerpc/kvm/book3s_hv_rm_xics.c |   5 ++
>>  arch/powerpc/kvm/book3s_xics.c       |  55 +++++++++++---
>>  arch/powerpc/kvm/book3s_xics.h       |   2 +
>>  arch/powerpc/kvm/mpic.c              |   4 +-
>>  arch/s390/kvm/Kconfig                |   1 +
>>  arch/s390/kvm/interrupt.c            |   3 +-
>>  arch/x86/kvm/Kconfig                 |   1 +
>>  include/linux/kvm_host.h             |  43 ++++-------
>>  virt/kvm/Kconfig                     |   3 +
>>  virt/kvm/eventfd.c                   | 134 ++++++++++++++++++++++++++---------
>>  virt/kvm/irq_comm.c                  |  24 +++----
>>  virt/kvm/irqchip.c                   |  98 ++++++++++---------------
>>  virt/kvm/kvm_main.c                  |   2 +-
>>  15 files changed, 227 insertions(+), 152 deletions(-)
>>
> 
> Applied for 3.17, thanks Eric and Cornelia for testing.
> 
> Paolo
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

This doesn't build without CONFIG_KVM_XICS, so I had to apply a fixup
patch to move some code from being under CONFIG_HAVE_KVM_IRQCHIP or
unconditional, to being conditional on CONFIG_HAVE_KVM_IRQFD.  I'll send
the patch shortly.

Also, please look into adding a trace_kvm_set_irq call to kvm_set_irq in
arch/powerpc/kvm/book3s_xics.c.

I would have preferred these snags to be fixed before (especially since
the breakage is simply with "make ppc64_defconfig"), but it's partly my
fault for delaying the review for so long.  And the series is good work
and a very nice cleanup of the irqfd architecture.

Assuming that the linux-next merge from tomorrow is fine, I'll send the
second pull request to Linus.

Paolo

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/6] IRQFD without IRQ routing, enabled for XICS
@ 2014-08-06 12:35     ` Paolo Bonzini
  0 siblings, 0 replies; 30+ messages in thread
From: Paolo Bonzini @ 2014-08-06 12:35 UTC (permalink / raw)
  To: Paul Mackerras, kvm, kvm-ppc
  Cc: Michael S. Tsirkin, Alexander Graf, Eric Auger

Il 05/08/2014 14:27, Paolo Bonzini ha scritto:
> Il 30/06/2014 12:51, Paul Mackerras ha scritto:
>> This series of patches provides a way to implement IRQFD support
>> without having to implement IRQ routing, and adds IRQFD support for
>> the XICS interrupt controller emulation.  (XICS is the interrupt
>> controller defined for the pSeries machine type, used on IBM POWER
>> servers).
>>
>> The basic approach is to make it easy for code other than irqchip.c to
>> provide a mapping from a global interrupt number (GSI) to an irq
>> routing entry (struct kvm_kernel_irq_routing_entry).  To make the
>> lifetime of this routing entry easier to manage, we change the IRQFD
>> code to keep a copy of the routing entry (for the MSI fast-path case)
>> rather than a pointer to the routing entry.  Since the copy can't be
>> updated atomically, we add a seqcount_t to make sure that when reading
>> it we get a copy that hasn't been half-way updated.
>>
>> Next we replace the hard-coded accesses outside irqchip.c to the
>> fields of the kvm_irq_routing_table struct with calls to accessor
>> functions in irqchip.c, namely kvm_irq_map_gsi() and
>> kvm_irq_map_chip_pin().  That enables us to move all references to the
>> kvm_irq_routing_table struct, and the definition of that struct, into
>> irqchip.c.
>>
>> Then we move the irq notifier implementation from irqchip.c into
>> eventfd.c and add a separate Kconfig option to enable IRQFD.  With
>> that we can enable IRQFD without irq routing, which we achieve by
>> compiling in eventfd.c but not irqchip.c, and providing an alternative
>> implementation of kvm_irq_map_gsi() and kvm_irq_map_chip_pin().
>>
>> The last patch does that for XICS.  With this series I can use
>> vhost-net with KVM guests, and I see the TCP bandwidth between guest
>> and host on a POWER8 machine go from around 700MB/s to over 2GB/s.
>>
>> I would like to see this go into 3.17.
>>
>>  arch/ia64/kvm/Kconfig                |   1 +
>>  arch/powerpc/kvm/Kconfig             |   3 +
>>  arch/powerpc/kvm/book3s_hv_rm_xics.c |   5 ++
>>  arch/powerpc/kvm/book3s_xics.c       |  55 +++++++++++---
>>  arch/powerpc/kvm/book3s_xics.h       |   2 +
>>  arch/powerpc/kvm/mpic.c              |   4 +-
>>  arch/s390/kvm/Kconfig                |   1 +
>>  arch/s390/kvm/interrupt.c            |   3 +-
>>  arch/x86/kvm/Kconfig                 |   1 +
>>  include/linux/kvm_host.h             |  43 ++++-------
>>  virt/kvm/Kconfig                     |   3 +
>>  virt/kvm/eventfd.c                   | 134 ++++++++++++++++++++++++++---------
>>  virt/kvm/irq_comm.c                  |  24 +++----
>>  virt/kvm/irqchip.c                   |  98 ++++++++++---------------
>>  virt/kvm/kvm_main.c                  |   2 +-
>>  15 files changed, 227 insertions(+), 152 deletions(-)
>>
> 
> Applied for 3.17, thanks Eric and Cornelia for testing.
> 
> Paolo
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

This doesn't build without CONFIG_KVM_XICS, so I had to apply a fixup
patch to move some code from being under CONFIG_HAVE_KVM_IRQCHIP or
unconditional, to being conditional on CONFIG_HAVE_KVM_IRQFD.  I'll send
the patch shortly.

Also, please look into adding a trace_kvm_set_irq call to kvm_set_irq in
arch/powerpc/kvm/book3s_xics.c.

I would have preferred these snags to be fixed before (especially since
the breakage is simply with "make ppc64_defconfig"), but it's partly my
fault for delaying the review for so long.  And the series is good work
and a very nice cleanup of the irqfd architecture.

Assuming that the linux-next merge from tomorrow is fine, I'll send the
second pull request to Linus.

Paolo

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/6] IRQFD without IRQ routing, enabled for XICS
  2014-08-06 12:35     ` Paolo Bonzini
@ 2014-08-07  9:49       ` Paul Mackerras
  -1 siblings, 0 replies; 30+ messages in thread
From: Paul Mackerras @ 2014-08-07  9:49 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: kvm, kvm-ppc, Michael S. Tsirkin, Alexander Graf, Eric Auger

On Wed, Aug 06, 2014 at 02:35:29PM +0200, Paolo Bonzini wrote:

> This doesn't build without CONFIG_KVM_XICS, so I had to apply a fixup
> patch to move some code from being under CONFIG_HAVE_KVM_IRQCHIP or
> unconditional, to being conditional on CONFIG_HAVE_KVM_IRQFD.  I'll send
> the patch shortly.

Oops, sorry, thanks for fixing it up.

> Also, please look into adding a trace_kvm_set_irq call to kvm_set_irq in
> arch/powerpc/kvm/book3s_xics.c.
> 
> I would have preferred these snags to be fixed before (especially since
> the breakage is simply with "make ppc64_defconfig"), but it's partly my
> fault for delaying the review for so long.  And the series is good work

... and I have been on vacation for the past three weeks, which didn't
help either.

> and a very nice cleanup of the irqfd architecture.
> 
> Assuming that the linux-next merge from tomorrow is fine, I'll send the
> second pull request to Linus.

Thanks,
Paul.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 0/6] IRQFD without IRQ routing, enabled for XICS
@ 2014-08-07  9:49       ` Paul Mackerras
  0 siblings, 0 replies; 30+ messages in thread
From: Paul Mackerras @ 2014-08-07  9:49 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: kvm, kvm-ppc, Michael S. Tsirkin, Alexander Graf, Eric Auger

On Wed, Aug 06, 2014 at 02:35:29PM +0200, Paolo Bonzini wrote:

> This doesn't build without CONFIG_KVM_XICS, so I had to apply a fixup
> patch to move some code from being under CONFIG_HAVE_KVM_IRQCHIP or
> unconditional, to being conditional on CONFIG_HAVE_KVM_IRQFD.  I'll send
> the patch shortly.

Oops, sorry, thanks for fixing it up.

> Also, please look into adding a trace_kvm_set_irq call to kvm_set_irq in
> arch/powerpc/kvm/book3s_xics.c.
> 
> I would have preferred these snags to be fixed before (especially since
> the breakage is simply with "make ppc64_defconfig"), but it's partly my
> fault for delaying the review for so long.  And the series is good work

... and I have been on vacation for the past three weeks, which didn't
help either.

> and a very nice cleanup of the irqfd architecture.
> 
> Assuming that the linux-next merge from tomorrow is fine, I'll send the
> second pull request to Linus.

Thanks,
Paul.

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2014-08-07  9:49 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-30 10:51 [PATCH 0/6] IRQFD without IRQ routing, enabled for XICS Paul Mackerras
2014-06-30 10:51 ` Paul Mackerras
2014-06-30 10:51 ` [PATCH 1/6] KVM: Don't keep reference to irq routing table in irqfd struct Paul Mackerras
2014-06-30 10:51   ` Paul Mackerras
2014-06-30 10:51 ` [PATCH 2/6] KVM: irqchip: Provide and use accessors for irq routing table Paul Mackerras
2014-06-30 10:51   ` Paul Mackerras
2014-06-30 10:51 ` [PATCH 3/6] KVM: Move all accesses to kvm::irq_routing into irqchip.c Paul Mackerras
2014-06-30 10:51   ` Paul Mackerras
2014-06-30 10:51 ` [PATCH 4/6] KVM: Move irq notifier implementation into eventfd.c Paul Mackerras
2014-06-30 10:51   ` Paul Mackerras
2014-06-30 10:51 ` [PATCH 5/6] KVM: Give IRQFD its own separate enabling Kconfig option Paul Mackerras
2014-06-30 10:51   ` Paul Mackerras
2014-06-30 10:51 ` [PATCH 6/6] KVM: PPC: Enable IRQFD support for the XICS interrupt controller Paul Mackerras
2014-06-30 10:51   ` Paul Mackerras
2014-06-30 12:43 ` [PATCH 0/6] IRQFD without IRQ routing, enabled for XICS Alexander Graf
2014-06-30 12:43   ` Alexander Graf
2014-06-30 21:25   ` Paul Mackerras
2014-06-30 21:25     ` Paul Mackerras
2014-07-13 22:30 ` Paul Mackerras
2014-07-13 22:30   ` Paul Mackerras
2014-07-14 14:18 ` Cornelia Huck
2014-07-14 14:18   ` Cornelia Huck
2014-07-24 15:47   ` Eric Auger
2014-07-24 15:47     ` Eric Auger
2014-08-05 12:27 ` Paolo Bonzini
2014-08-05 12:27   ` Paolo Bonzini
2014-08-06 12:35   ` Paolo Bonzini
2014-08-06 12:35     ` Paolo Bonzini
2014-08-07  9:49     ` Paul Mackerras
2014-08-07  9:49       ` Paul Mackerras

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.