All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/7] PV on HVM: receive interrupts as xen events
@ 2010-10-12 16:34 Stefano Stabellini
  2010-10-12 16:34 ` [PATCH v4 1/7] xen: support pirq != irq stefano.stabellini
                   ` (6 more replies)
  0 siblings, 7 replies; 13+ messages in thread
From: Stefano Stabellini @ 2010-10-12 16:34 UTC (permalink / raw)
  To: linux-kernel
  Cc: xen-devel, Jeremy Fitzhardinge, Konrad Rzeszutek Wilk,
	Stefano Stabellini

Hi all,
this patch series introduces some performance improvements for xen PV on
HVM guests: interacting with the emulated APIC is slow because it causes
traps in the hypervisor while receiving xen events using the vector callback
mechanism allow us to skip all that. For this reason we remap interrupts
and MSIs into xen pirqs so that from that point on we can receive them
as xen events instead.
This series is based on Konrad's pcifront series:

http://lkml.org/lkml/2010/10/12/207

and requires a patch to xen and a patch to qemu-xen (both sent to the
list).


New changes in v4:
- xen_hvm_register_pirq has been made static;

- the functions in arch/x86/pci/xen.c that depends on CONFIG_ACPI have
been ifdef'ed.


The list of patches with diffstat follows:

Jeremy Fitzhardinge (2):
      acpi: use indirect call to register gsi in different modes
      xen: add xen hvm acpi_register_gsi variant

Stefano Stabellini (5):
      xen: support pirq != irq
      xen: get the maximum number of pirqs from xen
      xen: implement xen_hvm_register_pirq
      xen: support GSI -> pirq remapping in PV on HVM guests
      xen: map MSIs into pirqs

 arch/x86/include/asm/acpi.h      |    3 +
 arch/x86/include/asm/xen/pci.h   |    5 ++
 arch/x86/kernel/acpi/boot.c      |   60 ++++++++++++++-----
 arch/x86/pci/xen.c               |  117 +++++++++++++++++++++++++++++++++++++
 drivers/xen/events.c             |  120 ++++++++++++++++++++++++++++++++------
 include/xen/events.h             |    3 +
 include/xen/interface/features.h |    3 +
 include/xen/interface/physdev.h  |   36 +++++++++++
 8 files changed, 311 insertions(+), 36 deletions(-)



A git tree with this series and Konrad's pcifront series on top of Linux
2.6.36-rc6 is available here:

git://xenbits.xen.org/people/sstabellini/linux-pvhvm.git 2.6.36-rc6-pvhvm-pirq-v4

Cheers,

Stefano Stabellini

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

* [PATCH v4 1/7] xen: support pirq != irq
  2010-10-12 16:34 [PATCH v4 0/7] PV on HVM: receive interrupts as xen events Stefano Stabellini
@ 2010-10-12 16:34 ` stefano.stabellini
  2010-10-12 16:34 ` [PATCH v4 2/7] xen: get the maximum number of pirqs from xen stefano.stabellini
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: stefano.stabellini @ 2010-10-12 16:34 UTC (permalink / raw)
  To: linux-kernel; +Cc: xen-devel, jeremy, konrad.wilk, Stefano Stabellini

From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

PHYSDEVOP_map_pirq might return a pirq different from what we asked if
we are running as an HVM guest, so we need to be able to support pirqs
that are different from linux irqs.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
 drivers/xen/events.c |   64 +++++++++++++++++++++++++++++++++++++------------
 include/xen/events.h |    1 +
 2 files changed, 49 insertions(+), 16 deletions(-)

diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index adad3a9..943f140 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -90,6 +90,7 @@ struct irq_info
 		unsigned short virq;
 		enum ipi_vector ipi;
 		struct {
+			unsigned short pirq;
 			unsigned short gsi;
 			unsigned char vector;
 			unsigned char flags;
@@ -100,6 +101,7 @@ struct irq_info
 #define PIRQ_SHAREABLE	(1 << 1)
 
 static struct irq_info *irq_info;
+static int *pirq_to_irq;
 
 static int *evtchn_to_irq;
 struct cpu_evtchn_s {
@@ -147,11 +149,12 @@ static struct irq_info mk_virq_info(unsigned short evtchn, unsigned short virq)
 			.cpu = 0, .u.virq = virq };
 }
 
-static struct irq_info mk_pirq_info(unsigned short evtchn,
+static struct irq_info mk_pirq_info(unsigned short evtchn, unsigned short pirq,
 				    unsigned short gsi, unsigned short vector)
 {
 	return (struct irq_info) { .type = IRQT_PIRQ, .evtchn = evtchn,
-			.cpu = 0, .u.pirq = { .gsi = gsi, .vector = vector } };
+			.cpu = 0,
+			.u.pirq = { .pirq = pirq, .gsi = gsi, .vector = vector } };
 }
 
 /*
@@ -193,6 +196,16 @@ static unsigned virq_from_irq(unsigned irq)
 	return info->u.virq;
 }
 
+static unsigned pirq_from_irq(unsigned irq)
+{
+	struct irq_info *info = info_for_irq(irq);
+
+	BUG_ON(info == NULL);
+	BUG_ON(info->type != IRQT_PIRQ);
+
+	return info->u.pirq.pirq;
+}
+
 static unsigned gsi_from_irq(unsigned irq)
 {
 	struct irq_info *info = info_for_irq(irq);
@@ -365,6 +378,16 @@ static int get_nr_hw_irqs(void)
 	return ret;
 }
 
+static int find_unbound_pirq(void)
+{
+	int i;
+	for (i = 0; i < nr_irqs; i++) {
+		if (pirq_to_irq[i] < 0)
+			return i;
+	}
+	return -1;
+}
+
 static int find_unbound_irq(void)
 {
 	int irq;
@@ -411,7 +434,7 @@ static bool identity_mapped_irq(unsigned irq)
 
 static void pirq_unmask_notify(int irq)
 {
-	struct physdev_eoi eoi = { .irq = irq };
+	struct physdev_eoi eoi = { .irq = pirq_from_irq(irq) };
 
 	if (unlikely(pirq_needs_eoi(irq))) {
 		int rc = HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi);
@@ -426,7 +449,7 @@ static void pirq_query_unmask(int irq)
 
 	BUG_ON(info->type != IRQT_PIRQ);
 
-	irq_status.irq = irq;
+	irq_status.irq = pirq_from_irq(irq);
 	if (HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status))
 		irq_status.flags = 0;
 
@@ -454,7 +477,7 @@ static unsigned int startup_pirq(unsigned int irq)
 	if (VALID_EVTCHN(evtchn))
 		goto out;
 
-	bind_pirq.pirq = irq;
+	bind_pirq.pirq = pirq_from_irq(irq);
 	/* NB. We are happy to share unless we are probing. */
 	bind_pirq.flags = info->u.pirq.flags & PIRQ_SHAREABLE ?
 					BIND_PIRQ__WILL_SHARE : 0;
@@ -557,28 +580,32 @@ static int find_irq_by_gsi(unsigned gsi)
 	return -1;
 }
 
-/* xen_allocate_irq might allocate irqs from the top down, as a
+int xen_allocate_pirq(unsigned gsi, int shareable, char *name)
+{
+	return xen_map_pirq_gsi(gsi, gsi, shareable, name);
+}
+
+/* xen_map_pirq_gsi might allocate irqs from the top down, as a
  * consequence don't assume that the irq number returned has a low value
  * or can be used as a pirq number unless you know otherwise.
  *
- * One notable exception is when xen_allocate_irq is called passing an
+ * One notable exception is when xen_map_pirq_gsi is called passing an
  * hardware gsi as argument, in that case the irq number returned
- * matches the gsi number passed as first argument.
-
- * Note: We don't assign an
- * event channel until the irq actually started up.  Return an
- * existing irq if we've already got one for the gsi.
+ * matches the gsi number passed as second argument.
+ *
+ * Note: We don't assign an event channel until the irq actually started
+ * up.  Return an existing irq if we've already got one for the gsi.
  */
-int xen_allocate_pirq(unsigned gsi, int shareable, char *name)
+int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name)
 {
-	int irq;
+	int irq = 0;
 	struct physdev_irq irq_op;
 
 	spin_lock(&irq_mapping_update_lock);
 
 	irq = find_irq_by_gsi(gsi);
 	if (irq != -1) {
-		printk(KERN_INFO "xen_allocate_pirq: returning irq %d for gsi %u\n",
+		printk(KERN_INFO "xen_map_pirq_gsi: returning irq %d for gsi %u\n",
 		       irq, gsi);
 		goto out;	/* XXX need refcount? */
 	}
@@ -608,8 +635,9 @@ int xen_allocate_pirq(unsigned gsi, int shareable, char *name)
 		goto out;
 	}
 
-	irq_info[irq] = mk_pirq_info(0, gsi, irq_op.vector);
+	irq_info[irq] = mk_pirq_info(0, pirq, gsi, irq_op.vector);
 	irq_info[irq].u.pirq.flags |= shareable ? PIRQ_SHAREABLE : 0;
+	pirq_to_irq[pirq] = irq;
 
 out:
 	spin_unlock(&irq_mapping_update_lock);
@@ -1329,6 +1357,10 @@ void __init xen_init_IRQ(void)
 				    GFP_KERNEL);
 	irq_info = kcalloc(nr_irqs, sizeof(*irq_info), GFP_KERNEL);
 
+	pirq_to_irq = kcalloc(nr_irqs, sizeof(*pirq_to_irq), GFP_KERNEL);
+	for (i = 0; i < nr_irqs; i++)
+		pirq_to_irq[i] = -1;
+
 	evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq),
 				    GFP_KERNEL);
 	for (i = 0; i < NR_EVENT_CHANNELS; i++)
diff --git a/include/xen/events.h b/include/xen/events.h
index c1717ca..deec8fa 100644
--- a/include/xen/events.h
+++ b/include/xen/events.h
@@ -71,6 +71,7 @@ void xen_hvm_evtchn_do_upcall(void);
  * GSIs are identity mapped; others are dynamically allocated as
  * usual. */
 int xen_allocate_pirq(unsigned gsi, int shareable, char *name);
+int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name);
 
 /* De-allocates the above mentioned physical interrupt. */
 int xen_destroy_irq(int irq);
-- 
1.5.6.5


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

* [PATCH v4 2/7] xen: get the maximum number of pirqs from xen
  2010-10-12 16:34 [PATCH v4 0/7] PV on HVM: receive interrupts as xen events Stefano Stabellini
  2010-10-12 16:34 ` [PATCH v4 1/7] xen: support pirq != irq stefano.stabellini
@ 2010-10-12 16:34 ` stefano.stabellini
  2010-10-12 16:34 ` [PATCH v4 3/7] xen: implement xen_hvm_register_pirq stefano.stabellini
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: stefano.stabellini @ 2010-10-12 16:34 UTC (permalink / raw)
  To: linux-kernel; +Cc: xen-devel, jeremy, konrad.wilk, Stefano Stabellini

From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

Use PHYSDEVOP_get_nr_pirqs to get the maximum number of pirqs from xen.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
 drivers/xen/events.c            |   30 ++++++++++++++++++++++++++----
 include/xen/interface/physdev.h |    6 ++++++
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 943f140..c77a44b 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -102,6 +102,7 @@ struct irq_info
 
 static struct irq_info *irq_info;
 static int *pirq_to_irq;
+static int nr_pirqs;
 
 static int *evtchn_to_irq;
 struct cpu_evtchn_s {
@@ -378,10 +379,12 @@ static int get_nr_hw_irqs(void)
 	return ret;
 }
 
+/* callers of this function should make sure that PHYSDEVOP_get_nr_pirqs
+ * succeeded otherwise nr_pirqs won't hold the right value */
 static int find_unbound_pirq(void)
 {
 	int i;
-	for (i = 0; i < nr_irqs; i++) {
+	for (i = nr_pirqs-1; i >= 0; i--) {
 		if (pirq_to_irq[i] < 0)
 			return i;
 	}
@@ -603,6 +606,13 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name)
 
 	spin_lock(&irq_mapping_update_lock);
 
+	if ((pirq > nr_pirqs) || (gsi > nr_irqs)) {
+		printk(KERN_WARNING "xen_map_pirq_gsi: %s %s is incorrect!\n",
+			pirq > nr_pirqs ? "nr_pirqs" :"",
+			gsi > nr_irqs ? "nr_irqs" : "");
+		goto out;
+	}
+
 	irq = find_irq_by_gsi(gsi);
 	if (irq != -1) {
 		printk(KERN_INFO "xen_map_pirq_gsi: returning irq %d for gsi %u\n",
@@ -1351,14 +1361,26 @@ void xen_callback_vector(void) {}
 
 void __init xen_init_IRQ(void)
 {
-	int i;
+	int i, rc;
+	struct physdev_nr_pirqs op_nr_pirqs;
 
 	cpu_evtchn_mask_p = kcalloc(nr_cpu_ids, sizeof(struct cpu_evtchn_s),
 				    GFP_KERNEL);
 	irq_info = kcalloc(nr_irqs, sizeof(*irq_info), GFP_KERNEL);
 
-	pirq_to_irq = kcalloc(nr_irqs, sizeof(*pirq_to_irq), GFP_KERNEL);
-	for (i = 0; i < nr_irqs; i++)
+	rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_nr_pirqs, &op_nr_pirqs);
+	if (rc < 0) {
+		nr_pirqs = nr_irqs;
+		if (rc != -ENOSYS)
+			printk(KERN_WARNING "PHYSDEVOP_get_nr_pirqs returned rc=%d\n", rc);
+	} else {
+		if (xen_pv_domain() && !xen_initial_domain())
+			nr_pirqs = max((int)op_nr_pirqs.nr_pirqs, nr_irqs);
+		else
+			nr_pirqs = op_nr_pirqs.nr_pirqs;
+	}
+	pirq_to_irq = kcalloc(nr_pirqs, sizeof(*pirq_to_irq), GFP_KERNEL);
+	for (i = 0; i < nr_pirqs; i++)
 		pirq_to_irq[i] = -1;
 
 	evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq),
diff --git a/include/xen/interface/physdev.h b/include/xen/interface/physdev.h
index cd69391..fbb5883 100644
--- a/include/xen/interface/physdev.h
+++ b/include/xen/interface/physdev.h
@@ -121,6 +121,12 @@ struct physdev_op {
 	} u;
 };
 
+#define PHYSDEVOP_get_nr_pirqs    22
+struct physdev_nr_pirqs {
+    /* OUT */
+    uint32_t nr_pirqs;
+};
+
 /*
  * Notify that some PIRQ-bound event channels have been unmasked.
  * ** This command is obsolete since interface version 0x00030202 and is **
-- 
1.5.6.5


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

* [PATCH v4 3/7] xen: implement xen_hvm_register_pirq
  2010-10-12 16:34 [PATCH v4 0/7] PV on HVM: receive interrupts as xen events Stefano Stabellini
  2010-10-12 16:34 ` [PATCH v4 1/7] xen: support pirq != irq stefano.stabellini
  2010-10-12 16:34 ` [PATCH v4 2/7] xen: get the maximum number of pirqs from xen stefano.stabellini
@ 2010-10-12 16:34 ` stefano.stabellini
  2010-10-12 16:34 ` [PATCH v4 4/7] acpi: use indirect call to register gsi in different modes stefano.stabellini
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: stefano.stabellini @ 2010-10-12 16:34 UTC (permalink / raw)
  To: linux-kernel; +Cc: xen-devel, jeremy, konrad.wilk, Stefano Stabellini

From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

xen_hvm_register_pirq allows the kernel to map a GSI into a Xen pirq and
receive the interrupt as an event channel from that point on.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
 arch/x86/pci/xen.c              |   38 ++++++++++++++++++++++++++++++++++++++
 drivers/xen/events.c            |    4 +++-
 include/xen/interface/physdev.h |   30 ++++++++++++++++++++++++++++++
 3 files changed, 71 insertions(+), 1 deletions(-)

diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index b19c873..e7f897b 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -17,6 +17,44 @@
 #include <xen/events.h>
 #include <asm/xen/pci.h>
 
+#ifdef CONFIG_ACPI
+static int xen_hvm_register_pirq(u32 gsi, int triggering)
+{
+	int rc, irq;
+	struct physdev_map_pirq map_irq;
+	int shareable = 0;
+	char *name;
+
+	if (!xen_hvm_domain())
+		return -1;
+
+	map_irq.domid = DOMID_SELF;
+	map_irq.type = MAP_PIRQ_TYPE_GSI;
+	map_irq.index = gsi;
+	map_irq.pirq = -1;
+
+	rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq);
+	if (rc) {
+		printk(KERN_WARNING "xen map irq failed %d\n", rc);
+		return -1;
+	}
+
+	if (triggering == ACPI_EDGE_SENSITIVE) {
+		shareable = 0;
+		name = "ioapic-edge";
+	} else {
+		shareable = 1;
+		name = "ioapic-level";
+	}
+
+	irq = xen_map_pirq_gsi(map_irq.pirq, gsi, shareable, name);
+
+	printk(KERN_DEBUG "xen: --> irq=%d, pirq=%d\n", irq, map_irq.pirq);
+
+	return irq;
+}
+#endif
+
 #if defined(CONFIG_PCI_MSI)
 #include <linux/msi.h>
 
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index c77a44b..4fed942 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -36,6 +36,7 @@
 #include <asm/idle.h>
 #include <asm/io_apic.h>
 #include <asm/sync_bitops.h>
+#include <asm/xen/pci.h>
 #include <asm/xen/hypercall.h>
 #include <asm/xen/hypervisor.h>
 
@@ -75,7 +76,8 @@ enum xen_irq_type {
  * event channel - irq->event channel mapping
  * cpu - cpu this event channel is bound to
  * index - type-specific information:
- *    PIRQ - vector, with MSB being "needs EIO"
+ *    PIRQ - vector, with MSB being "needs EIO", or physical IRQ of the HVM
+ *           guest, or GSI (real passthrough IRQ) of the device.
  *    VIRQ - virq number
  *    IPI - IPI vector
  *    EVTCHN -
diff --git a/include/xen/interface/physdev.h b/include/xen/interface/physdev.h
index fbb5883..69a72b9 100644
--- a/include/xen/interface/physdev.h
+++ b/include/xen/interface/physdev.h
@@ -106,6 +106,36 @@ struct physdev_irq {
 	uint32_t vector;
 };
 
+#define MAP_PIRQ_TYPE_MSI		0x0
+#define MAP_PIRQ_TYPE_GSI		0x1
+#define MAP_PIRQ_TYPE_UNKNOWN		0x2
+
+#define PHYSDEVOP_map_pirq		13
+struct physdev_map_pirq {
+    domid_t domid;
+    /* IN */
+    int type;
+    /* IN */
+    int index;
+    /* IN or OUT */
+    int pirq;
+    /* IN */
+    int bus;
+    /* IN */
+    int devfn;
+    /* IN */
+    int entry_nr;
+    /* IN */
+    uint64_t table_base;
+};
+
+#define PHYSDEVOP_unmap_pirq		14
+struct physdev_unmap_pirq {
+    domid_t domid;
+    /* IN */
+    int pirq;
+};
+
 /*
  * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
  * hypercall since 0x00030202.
-- 
1.5.6.5


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

* [PATCH v4 4/7] acpi: use indirect call to register gsi in different modes
  2010-10-12 16:34 [PATCH v4 0/7] PV on HVM: receive interrupts as xen events Stefano Stabellini
                   ` (2 preceding siblings ...)
  2010-10-12 16:34 ` [PATCH v4 3/7] xen: implement xen_hvm_register_pirq stefano.stabellini
@ 2010-10-12 16:34 ` stefano.stabellini
  2010-10-12 16:53   ` Konrad Rzeszutek Wilk
  2010-10-14 21:32   ` Rafael J. Wysocki
  2010-10-12 16:34 ` [PATCH v4 5/7] xen: add xen hvm acpi_register_gsi variant stefano.stabellini
                   ` (2 subsequent siblings)
  6 siblings, 2 replies; 13+ messages in thread
From: stefano.stabellini @ 2010-10-12 16:34 UTC (permalink / raw)
  To: linux-kernel; +Cc: xen-devel, jeremy, konrad.wilk, Jeremy Fitzhardinge

From: Jeremy Fitzhardinge <jeremy@goop.org>

Rather than using a tree of conditionals, use function pointer
for acpi_register_gsi.

Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
 arch/x86/kernel/acpi/boot.c |   59 ++++++++++++++++++++++++++++++------------
 1 files changed, 42 insertions(+), 17 deletions(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index c05872a..031f0c2 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -513,35 +513,61 @@ int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
 	return 0;
 }
 
-/*
- * success: return IRQ number (>=0)
- * failure: return < 0
- */
-int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
+static int acpi_register_gsi_pic(struct device *dev, u32 gsi,
+				 int trigger, int polarity)
 {
-	unsigned int irq;
-	unsigned int plat_gsi = gsi;
-
 #ifdef CONFIG_PCI
 	/*
 	 * Make sure all (legacy) PCI IRQs are set as level-triggered.
 	 */
-	if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) {
-		if (trigger == ACPI_LEVEL_SENSITIVE)
-			eisa_set_level_irq(gsi);
-	}
+	if (trigger == ACPI_LEVEL_SENSITIVE)
+		eisa_set_level_irq(gsi);
 #endif
 
+	return gsi;
+}
+
+static int acpi_register_gsi_ioapic(struct device *dev, u32 gsi,
+				    int trigger, int polarity)
+{
 #ifdef CONFIG_X86_IO_APIC
-	if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) {
-		plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity);
-	}
+	gsi = mp_register_gsi(dev, gsi, trigger, polarity);
 #endif
+
+	return gsi;
+}
+
+static int (*__acpi_register_gsi)(struct device *dev, u32 gsi, int trigger, int polarity) = acpi_register_gsi_pic;
+
+/*
+ * success: return IRQ number (>=0)
+ * failure: return < 0
+ */
+int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
+{
+	unsigned int irq;
+	unsigned int plat_gsi = gsi;
+
+	plat_gsi = (*__acpi_register_gsi)(dev, gsi, trigger, polarity);
 	irq = gsi_to_irq(plat_gsi);
 
 	return irq;
 }
 
+void __init acpi_set_irq_model_pic(void)
+{
+	acpi_irq_model = ACPI_IRQ_MODEL_PIC;
+	__acpi_register_gsi = acpi_register_gsi_pic;
+	acpi_ioapic = 0;
+}
+
+void __init acpi_set_irq_model_ioapic(void)
+{
+	acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
+	__acpi_register_gsi = acpi_register_gsi_ioapic;
+	acpi_ioapic = 1;
+}
+
 /*
  *  ACPI based hotplug support for CPU
  */
@@ -1259,8 +1285,7 @@ static void __init acpi_process_madt(void)
 			 */
 			error = acpi_parse_madt_ioapic_entries();
 			if (!error) {
-				acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
-				acpi_ioapic = 1;
+				acpi_set_irq_model_ioapic();
 
 				smp_found_config = 1;
 			}
-- 
1.5.6.5


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

* [PATCH v4 5/7] xen: add xen hvm acpi_register_gsi variant
  2010-10-12 16:34 [PATCH v4 0/7] PV on HVM: receive interrupts as xen events Stefano Stabellini
                   ` (3 preceding siblings ...)
  2010-10-12 16:34 ` [PATCH v4 4/7] acpi: use indirect call to register gsi in different modes stefano.stabellini
@ 2010-10-12 16:34 ` stefano.stabellini
  2010-10-12 16:52   ` Konrad Rzeszutek Wilk
  2010-10-14 21:34   ` Rafael J. Wysocki
  2010-10-12 16:34 ` [PATCH v4 6/7] xen: support GSI -> pirq remapping in PV on HVM guests stefano.stabellini
  2010-10-12 16:34 ` [PATCH v4 7/7] xen: map MSIs into pirqs stefano.stabellini
  6 siblings, 2 replies; 13+ messages in thread
From: stefano.stabellini @ 2010-10-12 16:34 UTC (permalink / raw)
  To: linux-kernel
  Cc: xen-devel, jeremy, konrad.wilk, Jeremy Fitzhardinge, Stefano Stabellini

From: Jeremy Fitzhardinge <jeremy@goop.org>

Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
 arch/x86/include/asm/acpi.h |    3 +++
 arch/x86/kernel/acpi/boot.c |    3 ++-
 arch/x86/pci/xen.c          |    6 ++++++
 3 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
index 92091de..55d106b 100644
--- a/arch/x86/include/asm/acpi.h
+++ b/arch/x86/include/asm/acpi.h
@@ -93,6 +93,9 @@ extern u8 acpi_sci_flags;
 extern int acpi_sci_override_gsi;
 void acpi_pic_sci_set_trigger(unsigned int, u16);
 
+extern int (*__acpi_register_gsi)(struct device *dev, u32 gsi,
+				  int trigger, int polarity);
+
 static inline void disable_acpi(void)
 {
 	acpi_disabled = 1;
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 031f0c2..71232b9 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -537,7 +537,8 @@ static int acpi_register_gsi_ioapic(struct device *dev, u32 gsi,
 	return gsi;
 }
 
-static int (*__acpi_register_gsi)(struct device *dev, u32 gsi, int trigger, int polarity) = acpi_register_gsi_pic;
+int (*__acpi_register_gsi)(struct device *dev, u32 gsi,
+			   int trigger, int polarity) = acpi_register_gsi_pic;
 
 /*
  * success: return IRQ number (>=0)
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index e7f897b..ef9b8b2 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -53,6 +53,12 @@ static int xen_hvm_register_pirq(u32 gsi, int triggering)
 
 	return irq;
 }
+
+static int acpi_register_gsi_xen_hvm(struct device *dev, u32 gsi,
+				 int trigger, int polarity)
+{
+	return xen_hvm_register_pirq(gsi, trigger);
+}
 #endif
 
 #if defined(CONFIG_PCI_MSI)
-- 
1.5.6.5


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

* [PATCH v4 6/7] xen: support GSI -> pirq remapping in PV on HVM guests
  2010-10-12 16:34 [PATCH v4 0/7] PV on HVM: receive interrupts as xen events Stefano Stabellini
                   ` (4 preceding siblings ...)
  2010-10-12 16:34 ` [PATCH v4 5/7] xen: add xen hvm acpi_register_gsi variant stefano.stabellini
@ 2010-10-12 16:34 ` stefano.stabellini
  2010-10-12 16:34 ` [PATCH v4 7/7] xen: map MSIs into pirqs stefano.stabellini
  6 siblings, 0 replies; 13+ messages in thread
From: stefano.stabellini @ 2010-10-12 16:34 UTC (permalink / raw)
  To: linux-kernel; +Cc: xen-devel, jeremy, konrad.wilk, Stefano Stabellini

From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

Disable pcifront when running on HVM: it is meant to be used with pv
guests that don't have PCI bus.

Use acpi_register_gsi_xen_hvm to remap GSIs into pirqs.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
 arch/x86/include/asm/xen/pci.h   |    5 +++++
 arch/x86/pci/xen.c               |   16 ++++++++++++++++
 drivers/xen/events.c             |    6 +++++-
 include/xen/interface/features.h |    3 +++
 4 files changed, 29 insertions(+), 1 deletions(-)

diff --git a/arch/x86/include/asm/xen/pci.h b/arch/x86/include/asm/xen/pci.h
index 449c82f..f89a42a 100644
--- a/arch/x86/include/asm/xen/pci.h
+++ b/arch/x86/include/asm/xen/pci.h
@@ -3,10 +3,15 @@
 
 #if defined(CONFIG_PCI_XEN)
 extern int __init pci_xen_init(void);
+extern int __init pci_xen_hvm_init(void);
 #define pci_xen 1
 #else
 #define pci_xen 0
 #define pci_xen_init (0)
+static inline int pci_xen_hvm_init(void)
+{
+	return -1;
+}
 #endif
 
 #if defined(CONFIG_PCI_MSI)
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index ef9b8b2..90a8f83 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -14,6 +14,7 @@
 
 #include <asm/xen/hypervisor.h>
 
+#include <xen/features.h>
 #include <xen/events.h>
 #include <asm/xen/pci.h>
 
@@ -189,3 +190,18 @@ int __init pci_xen_init(void)
 #endif
 	return 0;
 }
+
+int __init pci_xen_hvm_init(void)
+{
+	if (!xen_feature(XENFEAT_hvm_pirqs))
+		return 0;
+
+#ifdef CONFIG_ACPI
+	/*
+	 * We don't want to change the actual ACPI delivery model,
+	 * just how GSIs get registered.
+	 */
+	__acpi_register_gsi = acpi_register_gsi_xen_hvm;
+#endif
+	return 0;
+}
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 4fed942..5e4fe09 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -624,7 +624,8 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name)
 
 	/* If we are a PV guest, we don't have GSIs (no ACPI passed). Therefore
 	 * we are using the !xen_initial_domain() to drop in the function.*/
-	if (identity_mapped_irq(gsi) || !xen_initial_domain()) {
+	if (identity_mapped_irq(gsi) || (!xen_initial_domain() &&
+				xen_pv_domain())) {
 		irq = gsi;
 		irq_to_desc_alloc_node(irq, 0);
 		dynamic_irq_init(irq);
@@ -1399,6 +1400,9 @@ void __init xen_init_IRQ(void)
 	if (xen_hvm_domain()) {
 		xen_callback_vector();
 		native_init_IRQ();
+		/* pci_xen_hvm_init must be called after native_init_IRQ so that
+		 * __acpi_register_gsi can point at the right function */
+		pci_xen_hvm_init();
 	} else {
 		irq_ctx_init(smp_processor_id());
 	}
diff --git a/include/xen/interface/features.h b/include/xen/interface/features.h
index 70d2563..b6ca39a 100644
--- a/include/xen/interface/features.h
+++ b/include/xen/interface/features.h
@@ -47,6 +47,9 @@
 /* x86: pvclock algorithm is safe to use on HVM */
 #define XENFEAT_hvm_safe_pvclock           9
 
+/* x86: pirq can be used by HVM guests */
+#define XENFEAT_hvm_pirqs           10
+
 #define XENFEAT_NR_SUBMAPS 1
 
 #endif /* __XEN_PUBLIC_FEATURES_H__ */
-- 
1.5.6.5


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

* [PATCH v4 7/7] xen: map MSIs into pirqs
  2010-10-12 16:34 [PATCH v4 0/7] PV on HVM: receive interrupts as xen events Stefano Stabellini
                   ` (5 preceding siblings ...)
  2010-10-12 16:34 ` [PATCH v4 6/7] xen: support GSI -> pirq remapping in PV on HVM guests stefano.stabellini
@ 2010-10-12 16:34 ` stefano.stabellini
  6 siblings, 0 replies; 13+ messages in thread
From: stefano.stabellini @ 2010-10-12 16:34 UTC (permalink / raw)
  To: linux-kernel; +Cc: xen-devel, jeremy, konrad.wilk, Stefano Stabellini

From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

Map MSIs into pirqs, writing 0 in the MSI vector data field and the pirq
number in the MSI destination id field.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
 arch/x86/pci/xen.c   |   57 ++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/xen/events.c |   22 +++++++++++++++++++
 include/xen/events.h |    2 +
 3 files changed, 81 insertions(+), 0 deletions(-)

diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index 90a8f83..fb20d05 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -64,10 +64,62 @@ static int acpi_register_gsi_xen_hvm(struct device *dev, u32 gsi,
 
 #if defined(CONFIG_PCI_MSI)
 #include <linux/msi.h>
+#include <asm/msidef.h>
 
 struct xen_pci_frontend_ops *xen_pci_frontend;
 EXPORT_SYMBOL_GPL(xen_pci_frontend);
 
+static void xen_msi_compose_msg(struct pci_dev *pdev, unsigned int pirq,
+		struct msi_msg *msg)
+{
+	/* We set vector == 0 to tell the hypervisor we don't care about it,
+	 * but we want a pirq setup instead.
+	 * We use the dest_id field to pass the pirq that we want. */
+	msg->address_hi = MSI_ADDR_BASE_HI | MSI_ADDR_EXT_DEST_ID(pirq);
+	msg->address_lo =
+		MSI_ADDR_BASE_LO |
+		MSI_ADDR_DEST_MODE_PHYSICAL |
+		MSI_ADDR_REDIRECTION_CPU |
+		MSI_ADDR_DEST_ID(pirq);
+
+	msg->data =
+		MSI_DATA_TRIGGER_EDGE |
+		MSI_DATA_LEVEL_ASSERT |
+		/* delivery mode reserved */
+		(3 << 8) |
+		MSI_DATA_VECTOR(0);
+}
+
+static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+{
+	int irq, pirq, ret = 0;
+	struct msi_desc *msidesc;
+	struct msi_msg msg;
+
+	list_for_each_entry(msidesc, &dev->msi_list, list) {
+		xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ?
+				"msi-x" : "msi", &irq, &pirq);
+		if (irq < 0 || pirq < 0)
+			goto error;
+		printk(KERN_DEBUG "xen: msi --> irq=%d, pirq=%d\n", irq, pirq);
+		xen_msi_compose_msg(dev, pirq, &msg);
+		ret = set_irq_msi(irq, msidesc);
+		if (ret < 0)
+			goto error_while;
+		write_msi_msg(irq, &msg);
+	}
+	return 0;
+
+error_while:
+	unbind_from_irqhandler(irq, NULL);
+error:
+	if (ret == -ENODEV)
+		dev_err(&dev->dev, "Xen PCI frontend has not registered" \
+				" MSI/MSI-X support!\n");
+
+	return ret;
+}
+
 /*
  * For MSI interrupts we have to use drivers/xen/event.s functions to
  * allocate an irq_desc and setup the right */
@@ -203,5 +255,10 @@ int __init pci_xen_hvm_init(void)
 	 */
 	__acpi_register_gsi = acpi_register_gsi_xen_hvm;
 #endif
+
+#ifdef CONFIG_PCI_MSI
+	x86_msi.setup_msi_irqs = xen_hvm_setup_msi_irqs;
+	x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
+#endif
 	return 0;
 }
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 5e4fe09..2edbf7c 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -658,6 +658,28 @@ out:
 	return irq;
 }
 
+void xen_allocate_pirq_msi(char *name, int *irq, int *pirq)
+{
+	spin_lock(&irq_mapping_update_lock);
+
+	*irq = find_unbound_irq();
+	if (*irq == -1)
+		goto out;
+
+	*pirq = find_unbound_pirq();
+	if (*pirq == -1)
+		goto out;
+
+	set_irq_chip_and_handler_name(*irq, &xen_pirq_chip,
+				      handle_level_irq, name);
+
+	irq_info[*irq] = mk_pirq_info(0, *pirq, 0, 0);
+	pirq_to_irq[*pirq] = *irq;
+
+out:
+	spin_unlock(&irq_mapping_update_lock);
+}
+
 int xen_destroy_irq(int irq)
 {
 	struct irq_desc *desc;
diff --git a/include/xen/events.h b/include/xen/events.h
index deec8fa..0c58db6 100644
--- a/include/xen/events.h
+++ b/include/xen/events.h
@@ -72,6 +72,8 @@ void xen_hvm_evtchn_do_upcall(void);
  * usual. */
 int xen_allocate_pirq(unsigned gsi, int shareable, char *name);
 int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name);
+/* Allocate an irq and a pirq to be used with MSIs. */
+void xen_allocate_pirq_msi(char *name, int *irq, int *pirq);
 
 /* De-allocates the above mentioned physical interrupt. */
 int xen_destroy_irq(int irq);
-- 
1.5.6.5


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

* Re: [PATCH v4 5/7] xen: add xen hvm acpi_register_gsi variant
  2010-10-12 16:34 ` [PATCH v4 5/7] xen: add xen hvm acpi_register_gsi variant stefano.stabellini
@ 2010-10-12 16:52   ` Konrad Rzeszutek Wilk
  2010-10-14 21:34   ` Rafael J. Wysocki
  1 sibling, 0 replies; 13+ messages in thread
From: Konrad Rzeszutek Wilk @ 2010-10-12 16:52 UTC (permalink / raw)
  To: stefano.stabellini, len.brown, pavel, rjw
  Cc: linux-kernel, xen-devel, jeremy, Jeremy Fitzhardinge

Hey Len, Pavel, Rafael,

Stefano forgot to put you guys as CC. Is this patch OK with
you guys? The full link for the patchset is: http://lkml.org/lkml/2010/10/12/246

On Tue, Oct 12, 2010 at 05:34:47PM +0100, stefano.stabellini@eu.citrix.com wrote:
> From: Jeremy Fitzhardinge <jeremy@goop.org>
> 
> Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> ---
>  arch/x86/include/asm/acpi.h |    3 +++
>  arch/x86/kernel/acpi/boot.c |    3 ++-
>  arch/x86/pci/xen.c          |    6 ++++++
>  3 files changed, 11 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
> index 92091de..55d106b 100644
> --- a/arch/x86/include/asm/acpi.h
> +++ b/arch/x86/include/asm/acpi.h
> @@ -93,6 +93,9 @@ extern u8 acpi_sci_flags;
>  extern int acpi_sci_override_gsi;
>  void acpi_pic_sci_set_trigger(unsigned int, u16);
>  
> +extern int (*__acpi_register_gsi)(struct device *dev, u32 gsi,
> +				  int trigger, int polarity);
> +
>  static inline void disable_acpi(void)
>  {
>  	acpi_disabled = 1;
> diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
> index 031f0c2..71232b9 100644
> --- a/arch/x86/kernel/acpi/boot.c
> +++ b/arch/x86/kernel/acpi/boot.c
> @@ -537,7 +537,8 @@ static int acpi_register_gsi_ioapic(struct device *dev, u32 gsi,
>  	return gsi;
>  }
>  
> -static int (*__acpi_register_gsi)(struct device *dev, u32 gsi, int trigger, int polarity) = acpi_register_gsi_pic;
> +int (*__acpi_register_gsi)(struct device *dev, u32 gsi,
> +			   int trigger, int polarity) = acpi_register_gsi_pic;
>  
>  /*
>   * success: return IRQ number (>=0)
> diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
> index e7f897b..ef9b8b2 100644
> --- a/arch/x86/pci/xen.c
> +++ b/arch/x86/pci/xen.c
> @@ -53,6 +53,12 @@ static int xen_hvm_register_pirq(u32 gsi, int triggering)
>  
>  	return irq;
>  }
> +
> +static int acpi_register_gsi_xen_hvm(struct device *dev, u32 gsi,
> +				 int trigger, int polarity)
> +{
> +	return xen_hvm_register_pirq(gsi, trigger);
> +}
>  #endif
>  
>  #if defined(CONFIG_PCI_MSI)
> -- 
> 1.5.6.5

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

* Re: [PATCH v4 4/7] acpi: use indirect call to register gsi in different modes
  2010-10-12 16:34 ` [PATCH v4 4/7] acpi: use indirect call to register gsi in different modes stefano.stabellini
@ 2010-10-12 16:53   ` Konrad Rzeszutek Wilk
  2010-10-14 21:32   ` Rafael J. Wysocki
  1 sibling, 0 replies; 13+ messages in thread
From: Konrad Rzeszutek Wilk @ 2010-10-12 16:53 UTC (permalink / raw)
  To: stefano.stabellini, len.brown, pavel, rjw
  Cc: linux-kernel, xen-devel, jeremy, Jeremy Fitzhardinge

Len, Pavel and Rafael:

Adding you guys as CC.

On Tue, Oct 12, 2010 at 05:34:46PM +0100, stefano.stabellini@eu.citrix.com wrote:
> From: Jeremy Fitzhardinge <jeremy@goop.org>
> 
> Rather than using a tree of conditionals, use function pointer
> for acpi_register_gsi.
> 
> Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
> Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> ---
>  arch/x86/kernel/acpi/boot.c |   59 ++++++++++++++++++++++++++++++------------
>  1 files changed, 42 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
> index c05872a..031f0c2 100644
> --- a/arch/x86/kernel/acpi/boot.c
> +++ b/arch/x86/kernel/acpi/boot.c
> @@ -513,35 +513,61 @@ int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
>  	return 0;
>  }
>  
> -/*
> - * success: return IRQ number (>=0)
> - * failure: return < 0
> - */
> -int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
> +static int acpi_register_gsi_pic(struct device *dev, u32 gsi,
> +				 int trigger, int polarity)
>  {
> -	unsigned int irq;
> -	unsigned int plat_gsi = gsi;
> -
>  #ifdef CONFIG_PCI
>  	/*
>  	 * Make sure all (legacy) PCI IRQs are set as level-triggered.
>  	 */
> -	if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) {
> -		if (trigger == ACPI_LEVEL_SENSITIVE)
> -			eisa_set_level_irq(gsi);
> -	}
> +	if (trigger == ACPI_LEVEL_SENSITIVE)
> +		eisa_set_level_irq(gsi);
>  #endif
>  
> +	return gsi;
> +}
> +
> +static int acpi_register_gsi_ioapic(struct device *dev, u32 gsi,
> +				    int trigger, int polarity)
> +{
>  #ifdef CONFIG_X86_IO_APIC
> -	if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) {
> -		plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity);
> -	}
> +	gsi = mp_register_gsi(dev, gsi, trigger, polarity);
>  #endif
> +
> +	return gsi;
> +}
> +
> +static int (*__acpi_register_gsi)(struct device *dev, u32 gsi, int trigger, int polarity) = acpi_register_gsi_pic;
> +
> +/*
> + * success: return IRQ number (>=0)
> + * failure: return < 0
> + */
> +int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
> +{
> +	unsigned int irq;
> +	unsigned int plat_gsi = gsi;
> +
> +	plat_gsi = (*__acpi_register_gsi)(dev, gsi, trigger, polarity);
>  	irq = gsi_to_irq(plat_gsi);
>  
>  	return irq;
>  }
>  
> +void __init acpi_set_irq_model_pic(void)
> +{
> +	acpi_irq_model = ACPI_IRQ_MODEL_PIC;
> +	__acpi_register_gsi = acpi_register_gsi_pic;
> +	acpi_ioapic = 0;
> +}
> +
> +void __init acpi_set_irq_model_ioapic(void)
> +{
> +	acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
> +	__acpi_register_gsi = acpi_register_gsi_ioapic;
> +	acpi_ioapic = 1;
> +}
> +
>  /*
>   *  ACPI based hotplug support for CPU
>   */
> @@ -1259,8 +1285,7 @@ static void __init acpi_process_madt(void)
>  			 */
>  			error = acpi_parse_madt_ioapic_entries();
>  			if (!error) {
> -				acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
> -				acpi_ioapic = 1;
> +				acpi_set_irq_model_ioapic();
>  
>  				smp_found_config = 1;
>  			}
> -- 
> 1.5.6.5

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

* Re: [PATCH v4 4/7] acpi: use indirect call to register gsi in different modes
  2010-10-12 16:34 ` [PATCH v4 4/7] acpi: use indirect call to register gsi in different modes stefano.stabellini
  2010-10-12 16:53   ` Konrad Rzeszutek Wilk
@ 2010-10-14 21:32   ` Rafael J. Wysocki
  2010-10-15 14:11     ` Stefano Stabellini
  1 sibling, 1 reply; 13+ messages in thread
From: Rafael J. Wysocki @ 2010-10-14 21:32 UTC (permalink / raw)
  To: stefano.stabellini
  Cc: linux-kernel, xen-devel, jeremy, konrad.wilk, Jeremy Fitzhardinge

On Tuesday, October 12, 2010, stefano.stabellini@eu.citrix.com wrote:
> From: Jeremy Fitzhardinge <jeremy@goop.org>
> 
> Rather than using a tree of conditionals, use function pointer
> for acpi_register_gsi.
> 
> Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
> Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>

Looks good to me.

Thanks,
Rafael


> ---
>  arch/x86/kernel/acpi/boot.c |   59 ++++++++++++++++++++++++++++++------------
>  1 files changed, 42 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
> index c05872a..031f0c2 100644
> --- a/arch/x86/kernel/acpi/boot.c
> +++ b/arch/x86/kernel/acpi/boot.c
> @@ -513,35 +513,61 @@ int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
>  	return 0;
>  }
>  
> -/*
> - * success: return IRQ number (>=0)
> - * failure: return < 0
> - */
> -int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
> +static int acpi_register_gsi_pic(struct device *dev, u32 gsi,
> +				 int trigger, int polarity)
>  {
> -	unsigned int irq;
> -	unsigned int plat_gsi = gsi;
> -
>  #ifdef CONFIG_PCI
>  	/*
>  	 * Make sure all (legacy) PCI IRQs are set as level-triggered.
>  	 */
> -	if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) {
> -		if (trigger == ACPI_LEVEL_SENSITIVE)
> -			eisa_set_level_irq(gsi);
> -	}
> +	if (trigger == ACPI_LEVEL_SENSITIVE)
> +		eisa_set_level_irq(gsi);
>  #endif
>  
> +	return gsi;
> +}
> +
> +static int acpi_register_gsi_ioapic(struct device *dev, u32 gsi,
> +				    int trigger, int polarity)
> +{
>  #ifdef CONFIG_X86_IO_APIC
> -	if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) {
> -		plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity);
> -	}
> +	gsi = mp_register_gsi(dev, gsi, trigger, polarity);
>  #endif
> +
> +	return gsi;
> +}
> +
> +static int (*__acpi_register_gsi)(struct device *dev, u32 gsi, int trigger, int polarity) = acpi_register_gsi_pic;
> +
> +/*
> + * success: return IRQ number (>=0)
> + * failure: return < 0
> + */
> +int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
> +{
> +	unsigned int irq;
> +	unsigned int plat_gsi = gsi;
> +
> +	plat_gsi = (*__acpi_register_gsi)(dev, gsi, trigger, polarity);
>  	irq = gsi_to_irq(plat_gsi);
>  
>  	return irq;
>  }
>  
> +void __init acpi_set_irq_model_pic(void)
> +{
> +	acpi_irq_model = ACPI_IRQ_MODEL_PIC;
> +	__acpi_register_gsi = acpi_register_gsi_pic;
> +	acpi_ioapic = 0;
> +}
> +
> +void __init acpi_set_irq_model_ioapic(void)
> +{
> +	acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
> +	__acpi_register_gsi = acpi_register_gsi_ioapic;
> +	acpi_ioapic = 1;
> +}
> +
>  /*
>   *  ACPI based hotplug support for CPU
>   */
> @@ -1259,8 +1285,7 @@ static void __init acpi_process_madt(void)
>  			 */
>  			error = acpi_parse_madt_ioapic_entries();
>  			if (!error) {
> -				acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
> -				acpi_ioapic = 1;
> +				acpi_set_irq_model_ioapic();
>  
>  				smp_found_config = 1;
>  			}
> 


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

* Re: [PATCH v4 5/7] xen: add xen hvm acpi_register_gsi variant
  2010-10-12 16:34 ` [PATCH v4 5/7] xen: add xen hvm acpi_register_gsi variant stefano.stabellini
  2010-10-12 16:52   ` Konrad Rzeszutek Wilk
@ 2010-10-14 21:34   ` Rafael J. Wysocki
  1 sibling, 0 replies; 13+ messages in thread
From: Rafael J. Wysocki @ 2010-10-14 21:34 UTC (permalink / raw)
  To: stefano.stabellini
  Cc: linux-kernel, xen-devel, jeremy, konrad.wilk, Jeremy Fitzhardinge

On Tuesday, October 12, 2010, stefano.stabellini@eu.citrix.com wrote:
> From: Jeremy Fitzhardinge <jeremy@goop.org>
> 
> Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>

I'm not really familiar with Xen, but the patch looks reasonable.

Thanks,
Rafael


> ---
>  arch/x86/include/asm/acpi.h |    3 +++
>  arch/x86/kernel/acpi/boot.c |    3 ++-
>  arch/x86/pci/xen.c          |    6 ++++++
>  3 files changed, 11 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
> index 92091de..55d106b 100644
> --- a/arch/x86/include/asm/acpi.h
> +++ b/arch/x86/include/asm/acpi.h
> @@ -93,6 +93,9 @@ extern u8 acpi_sci_flags;
>  extern int acpi_sci_override_gsi;
>  void acpi_pic_sci_set_trigger(unsigned int, u16);
>  
> +extern int (*__acpi_register_gsi)(struct device *dev, u32 gsi,
> +				  int trigger, int polarity);
> +
>  static inline void disable_acpi(void)
>  {
>  	acpi_disabled = 1;
> diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
> index 031f0c2..71232b9 100644
> --- a/arch/x86/kernel/acpi/boot.c
> +++ b/arch/x86/kernel/acpi/boot.c
> @@ -537,7 +537,8 @@ static int acpi_register_gsi_ioapic(struct device *dev, u32 gsi,
>  	return gsi;
>  }
>  
> -static int (*__acpi_register_gsi)(struct device *dev, u32 gsi, int trigger, int polarity) = acpi_register_gsi_pic;
> +int (*__acpi_register_gsi)(struct device *dev, u32 gsi,
> +			   int trigger, int polarity) = acpi_register_gsi_pic;
>  
>  /*
>   * success: return IRQ number (>=0)
> diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
> index e7f897b..ef9b8b2 100644
> --- a/arch/x86/pci/xen.c
> +++ b/arch/x86/pci/xen.c
> @@ -53,6 +53,12 @@ static int xen_hvm_register_pirq(u32 gsi, int triggering)
>  
>  	return irq;
>  }
> +
> +static int acpi_register_gsi_xen_hvm(struct device *dev, u32 gsi,
> +				 int trigger, int polarity)
> +{
> +	return xen_hvm_register_pirq(gsi, trigger);
> +}
>  #endif
>  
>  #if defined(CONFIG_PCI_MSI)
> 


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

* Re: [PATCH v4 4/7] acpi: use indirect call to register gsi in different modes
  2010-10-14 21:32   ` Rafael J. Wysocki
@ 2010-10-15 14:11     ` Stefano Stabellini
  0 siblings, 0 replies; 13+ messages in thread
From: Stefano Stabellini @ 2010-10-15 14:11 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Stefano Stabellini, linux-kernel, xen-devel, jeremy, konrad.wilk,
	Jeremy Fitzhardinge

On Thu, 14 Oct 2010, Rafael J. Wysocki wrote:
> On Tuesday, October 12, 2010, stefano.stabellini@eu.citrix.com wrote:
> > From: Jeremy Fitzhardinge <jeremy@goop.org>
> > 
> > Rather than using a tree of conditionals, use function pointer
> > for acpi_register_gsi.
> > 
> > Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
> > Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> 
> Looks good to me.
> 

Thank you very much for taking the time to read these two patches!


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

end of thread, other threads:[~2010-10-15 14:11 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-10-12 16:34 [PATCH v4 0/7] PV on HVM: receive interrupts as xen events Stefano Stabellini
2010-10-12 16:34 ` [PATCH v4 1/7] xen: support pirq != irq stefano.stabellini
2010-10-12 16:34 ` [PATCH v4 2/7] xen: get the maximum number of pirqs from xen stefano.stabellini
2010-10-12 16:34 ` [PATCH v4 3/7] xen: implement xen_hvm_register_pirq stefano.stabellini
2010-10-12 16:34 ` [PATCH v4 4/7] acpi: use indirect call to register gsi in different modes stefano.stabellini
2010-10-12 16:53   ` Konrad Rzeszutek Wilk
2010-10-14 21:32   ` Rafael J. Wysocki
2010-10-15 14:11     ` Stefano Stabellini
2010-10-12 16:34 ` [PATCH v4 5/7] xen: add xen hvm acpi_register_gsi variant stefano.stabellini
2010-10-12 16:52   ` Konrad Rzeszutek Wilk
2010-10-14 21:34   ` Rafael J. Wysocki
2010-10-12 16:34 ` [PATCH v4 6/7] xen: support GSI -> pirq remapping in PV on HVM guests stefano.stabellini
2010-10-12 16:34 ` [PATCH v4 7/7] xen: map MSIs into pirqs stefano.stabellini

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.