Skip to contentSkip to conversation

New paravirtual PCI front-end for Hyper-V VMs

PATCH Superseded [email protected] 4 participants 19 messages Sep 11, 2015 – Sep 21, 2015

Subsystems (13)

v2 of 10 Superseded Latest is v10 →

lore
Share & tools
lore
#0 lore raw

v2 cover New paravirtual PCI front-end for Hyper-V VMs

From: Jake Oshins <[email protected]>

The patch series updates the one sent about a month ago in three ways. It integrated with other IRQ domain work done in linux-next in that time, it distributes interrupts to multiple virtual processors in the guest VM, and it incorporates feedback from Thomas Gleixner and others.

These patches change the IRQ domain code so that an IRQ domain can match on both bus type and on the PCI domain. The IRQ domain match code is modified so that IRQ domains can have a "rank," allowing for a default one which matches every x86 PC and more specific ones that replace the default.

The next step is to make it possible to implement an IRQ domain in a module, by exporting a few functions. This seems to make sense here, rather than linking it into the kernel, because pulling it into the kernel would involve pulling a lot of other Hyper-V-related code into the kernel, since the IRQ domain implementation has to send messages to and receive messages from the hypervisor, and those facilities are currently built as modules.

After that, a couple of new Hyper-V-related facilities are exported from hv_vmbus.ko, so that the PCI front end can correlate Linux CPUs with virtual processor IDs and to make hypercalls.

The last patch is a new front-end driver that exposes new root PCI buses that (virtually) contain devices being passed through into the VM.

Jake Oshins (12):
kernel:irq: Change signature of irq_domain_ops match() method, adding
*bus_data
kernel:irq: Change signature of irq_find_matching_host() kernel:irq: Allow for ranked matches on IRQ domains drivers:pci: Add IRQ domain lookup by PCI domain drivers:hv: Export a function that maps Linux CPU num onto Hyper-V
proc num
drivers:hv: Export do_hypercall()
drivers:x86:pci: Make it possible to implement a PCI MSI IRQ Domain in
a module.
drivers:pci:msi: Store PCI domain (segment) as part of IRQ domain kernel:irq: Implement msi match function
kernel:irq: Return a higher ranked match when the IRQ domain matches a
specific PCI domain
drivers:hv: Define the channel type for Hyper-V PCI Express
pass-through
drivers:pci:hv: New paravirtual PCI front-end for Hyper-V VMs

 MAINTAINERS                                      |    1 +
 arch/powerpc/platforms/512x/mpc5121_ads_cpld.c   |    2 +-
 arch/powerpc/platforms/cell/interrupt.c          |    2 +-
 arch/powerpc/platforms/embedded6xx/flipper-pic.c |    3 +-
 arch/powerpc/platforms/powermac/pic.c            |    3 +-
 arch/powerpc/platforms/powernv/opal-irqchip.c    |    2 +-
 arch/powerpc/platforms/ps3/interrupt.c           |    2 +-
 arch/powerpc/sysdev/ehv_pic.c                    |    3 +-
 arch/powerpc/sysdev/i8259.c                      |    2 +-
 arch/powerpc/sysdev/ipic.c                       |    2 +-
 arch/powerpc/sysdev/mpic.c                       |    2 +-
 arch/powerpc/sysdev/qe_lib/qe_ic.c               |    2 +-
 arch/powerpc/sysdev/xics/xics-common.c           |    2 +-
 arch/x86/include/asm/msi.h                       |    4 +
 arch/x86/kernel/apic/msi.c                       |    5 +-
 arch/x86/kernel/apic/vector.c                    |    2 +
 drivers/hv/hv.c                                  |    3 +-
 drivers/hv/vmbus_drv.c                           |   17 +
 drivers/irqchip/irq-gic-v3-its-pci-msi.c         |    2 +-
 drivers/irqchip/irq-gic-v3-its-platform-msi.c    |    2 +-
 drivers/of/irq.c                                 |    2 +-
 drivers/pci/Kconfig                              |    7 +
 drivers/pci/host/Makefile                        |    1 +
 drivers/pci/host/hv_pcifront.c                   | 2244 ++++++++++++++++++++++
 drivers/pci/msi.c                                |    2 +
 drivers/pci/of.c                                 |    2 +-
 drivers/pci/probe.c                              |   11 +
 include/linux/hyperv.h                           |   14 +
 include/linux/irqdomain.h                        |    9 +-
 include/linux/msi.h                              |    4 +
 kernel/irq/chip.c                                |    1 +
 kernel/irq/irqdomain.c                           |   48 +-
 kernel/irq/msi.c                                 |   24 +
 33 files changed, 2394 insertions(+), 38 deletions(-)
 create mode 100644 drivers/pci/host/hv_pcifront.c
Signature · 1 line
1.9.1
#1 lore raw

PATCH v2 1/12 kernel:irq: Change signature of irq_domain_ops match() method, adding *bus_data

From: Jake Oshins <[email protected]>

The current irq_domain_ops allows an IRQ domain to match on bus type, but not a specific PCI bus heirarchy. This patch introduces a bus_data parameter, intended to allow a more specific match. This patch does nothing more than introduce that parameter and change all the implementations' signatures.

---
 arch/powerpc/platforms/512x/mpc5121_ads_cpld.c   | 2 +-
 arch/powerpc/platforms/cell/interrupt.c          | 2 +-
 arch/powerpc/platforms/embedded6xx/flipper-pic.c | 3 ++-
 arch/powerpc/platforms/powermac/pic.c            | 3 ++-
 arch/powerpc/platforms/powernv/opal-irqchip.c    | 2 +-
 arch/powerpc/platforms/ps3/interrupt.c           | 2 +-
 arch/powerpc/sysdev/ehv_pic.c                    | 3 ++-
 arch/powerpc/sysdev/i8259.c                      | 2 +-
 arch/powerpc/sysdev/ipic.c                       | 2 +-
 arch/powerpc/sysdev/mpic.c                       | 2 +-
 arch/powerpc/sysdev/qe_lib/qe_ic.c               | 2 +-
 arch/powerpc/sysdev/xics/xics-common.c           | 2 +-
 include/linux/irqdomain.h                        | 2 +-
 kernel/irq/irqdomain.c                           | 2 +-
 14 files changed, 17 insertions(+), 14 deletions(-)
arch/powerpc/platforms/512x/mpc5121_ads_cpld.c +1 -1
index 11090ab..1d12a63 100644
@@ -124,7 +124,7 @@ cpld_pic_cascade(unsigned int irq, struct irq_desc *desc)
 
 static int
 cpld_pic_host_match(struct irq_domain *h, struct device_node *node,
-		    enum irq_domain_bus_token bus_token)
+		    enum irq_domain_bus_token bus_token, void *bus_data)
 {
 	return cpld_pic_node == node;
 }
arch/powerpc/platforms/cell/interrupt.c +1 -1
index a15f1ef..3450bb8 100644
@@ -223,7 +223,7 @@ void iic_request_IPIs(void)
 
 
 static int iic_host_match(struct irq_domain *h, struct device_node *node,
-			  enum irq_domain_bus_token bus_token)
+			  enum irq_domain_bus_token bus_token, void *bus_data)
 {
 	return of_device_is_compatible(node,
 				    "IBM,CBEA-Internal-Interrupt-Controller");
arch/powerpc/platforms/embedded6xx/flipper-pic.c +2 -1
index b7866e0..1615990 100644
@@ -109,7 +109,8 @@ static int flipper_pic_map(struct irq_domain *h, unsigned int virq,
 }
 
 static int flipper_pic_match(struct irq_domain *h, struct device_node *np,
-			     enum irq_domain_bus_token bus_token)
+			     enum irq_domain_bus_token bus_token,
+			     void *bus_data)
 {
 	return 1;
 }
arch/powerpc/platforms/powermac/pic.c +2 -1
index 6f4f8b0..035766a 100644
@@ -269,7 +269,8 @@ static struct irqaction gatwick_cascade_action = {
 };
 
 static int pmac_pic_host_match(struct irq_domain *h, struct device_node *node,
-			       enum irq_domain_bus_token bus_token)
+			       enum irq_domain_bus_token bus_token,
+			       void *bus_data)
 {
 	/* We match all, we don't always have a node anyway */
 	return 1;
arch/powerpc/platforms/powernv/opal-irqchip.c +1 -1
index 2c91ee7..f83097e 100644
@@ -135,7 +135,7 @@ static void opal_handle_irq_work(struct irq_work *work)
 }
 
 static int opal_event_match(struct irq_domain *h, struct device_node *node,
-			    enum irq_domain_bus_token bus_token)
+			    enum irq_domain_bus_token bus_token, void *bus_data)
 {
 	return h->of_node == node;
 }
arch/powerpc/platforms/ps3/interrupt.c +1 -1
index 638c406..049fb23 100644
@@ -679,7 +679,7 @@ static int ps3_host_map(struct irq_domain *h, unsigned int virq,
 }
 
 static int ps3_host_match(struct irq_domain *h, struct device_node *np,
-			  enum irq_domain_bus_token bus_token)
+			  enum irq_domain_bus_token bus_token, void *bus_data)
 {
 	/* Match all */
 	return 1;
arch/powerpc/sysdev/ehv_pic.c +2 -1
index eca0b00..4d10a2c 100644
@@ -178,7 +178,8 @@ unsigned int ehv_pic_get_irq(void)
 }
 
 static int ehv_pic_host_match(struct irq_domain *h, struct device_node *node,
-			      enum irq_domain_bus_token bus_token)
+			      enum irq_domain_bus_token bus_token,
+			      void *bus_data)
 {
 	/* Exact match, unless ehv_pic node is NULL */
 	return h->of_node == NULL || h->of_node == node;
arch/powerpc/sysdev/i8259.c +1 -1
index e1a9c2c..78360fe 100644
@@ -163,7 +163,7 @@ static struct resource pic_edgectrl_iores = {
 };
 
 static int i8259_host_match(struct irq_domain *h, struct device_node *node,
-			    enum irq_domain_bus_token bus_token)
+			    enum irq_domain_bus_token bus_token, void *bus_data)
 {
 	return h->of_node == NULL || h->of_node == node;
 }
arch/powerpc/sysdev/ipic.c +1 -1
index 6b2b689..93eca76 100644
@@ -672,7 +672,7 @@ static struct irq_chip ipic_edge_irq_chip = {
 };
 
 static int ipic_host_match(struct irq_domain *h, struct device_node *node,
-			   enum irq_domain_bus_token bus_token)
+			   enum irq_domain_bus_token bus_token, void *bus_data)
 {
 	/* Exact match, unless ipic node is NULL */
 	return h->of_node == NULL || h->of_node == node;
arch/powerpc/sysdev/mpic.c +1 -1
index 97a8ae8..24be672 100644
@@ -1008,7 +1008,7 @@ static struct irq_chip mpic_irq_ht_chip = {
 
 
 static int mpic_host_match(struct irq_domain *h, struct device_node *node,
-			   enum irq_domain_bus_token bus_token)
+			   enum irq_domain_bus_token bus_token, void *bus_data)
 {
 	/* Exact match, unless mpic node is NULL */
 	return h->of_node == NULL || h->of_node == node;
arch/powerpc/sysdev/qe_lib/qe_ic.c +1 -1
index 47b352e..dadc286 100644
@@ -245,7 +245,7 @@ static struct irq_chip qe_ic_irq_chip = {
 };
 
 static int qe_ic_host_match(struct irq_domain *h, struct device_node *node,
-			    enum irq_domain_bus_token bus_token)
+			    enum irq_domain_bus_token bus_token, void *bus_data)
 {
 	/* Exact match, unless qe_ic node is NULL */
 	return h->of_node == NULL || h->of_node == node;
arch/powerpc/sysdev/xics/xics-common.c +1 -1
index 47e43b7..fae4901 100644
@@ -299,7 +299,7 @@ int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask,
 #endif /* CONFIG_SMP */
 
 static int xics_host_match(struct irq_domain *h, struct device_node *node,
-			   enum irq_domain_bus_token bus_token)
+			   enum irq_domain_bus_token bus_token, void *bus_data)
 {
 	struct ics *ics;
 
include/linux/irqdomain.h +1 -1
index d3ca792..4d89f98 100644
@@ -76,7 +76,7 @@ enum irq_domain_bus_token {
  */
 struct irq_domain_ops {
 	int (*match)(struct irq_domain *d, struct device_node *node,
-		     enum irq_domain_bus_token bus_token);
+		     enum irq_domain_bus_token bus_token, void *bus_data);
 	int (*map)(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw);
 	void (*unmap)(struct irq_domain *d, unsigned int virq);
 	int (*xlate)(struct irq_domain *d, struct device_node *node,
kernel/irq/irqdomain.c +1 -1
index 79baaf8..8a8ef31 100644
@@ -209,7 +209,7 @@ struct irq_domain *irq_find_matching_host(struct device_node *node,
 	mutex_lock(&irq_domain_mutex);
 	list_for_each_entry(h, &irq_domain_list, link) {
 		if (h->ops->match)
-			rc = h->ops->match(h, node, bus_token);
+			rc = h->ops->match(h, node, bus_token, NULL);
 		else
 			rc = ((h->of_node != NULL) && (h->of_node == node) &&
 			      ((bus_token == DOMAIN_BUS_ANY) ||
Signature · 1 line
1.9.1
#2 lore raw

PATCH v2 2/12 kernel:irq: Change signature of irq_find_matching_host()

In reply to [email protected]

From: Jake Oshins <[email protected]>

In order to use the facility introduced in the last patch (the ability to match on both bus type and something that identifies the specific bus of that type,) irq_find_matching_host() needs to take that bus-specific parameter.

---
 drivers/irqchip/irq-gic-v3-its-pci-msi.c      | 2 +-
 drivers/irqchip/irq-gic-v3-its-platform-msi.c | 2 +-
 drivers/of/irq.c                              | 2 +-
 drivers/pci/of.c                              | 2 +-
 include/linux/irqdomain.h                     | 5 +++--
 kernel/irq/irqdomain.c                        | 6 ++++--
 6 files changed, 11 insertions(+), 8 deletions(-)
drivers/irqchip/irq-gic-v3-its-pci-msi.c +1 -1
index cf351c6..51521b5 100644
@@ -118,7 +118,7 @@ static int __init its_pci_msi_init(void)
 		if (!of_property_read_bool(np, "msi-controller"))
 			continue;
 
-		parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS);
+		parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS, NULL);
 		if (!parent || !msi_get_domain_info(parent)) {
 			pr_err("%s: unable to locate ITS domain\n",
 			       np->full_name);
drivers/irqchip/irq-gic-v3-its-platform-msi.c +1 -1
index a865505..5a3ac02 100644
@@ -71,7 +71,7 @@ static int __init its_pmsi_init(void)
 		if (!of_property_read_bool(np, "msi-controller"))
 			continue;
 
-		parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS);
+		parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS, NULL);
 		if (!parent || !msi_get_domain_info(parent)) {
 			pr_err("%s: unable to locate ITS domain\n",
 			       np->full_name);
drivers/of/irq.c +1 -1
index 55317fa..1c9c944 100644
@@ -593,7 +593,7 @@ void of_msi_configure(struct device *dev, struct device_node *np)
 	if (!msi_np)
 		return;
 
-	d = irq_find_matching_host(msi_np, DOMAIN_BUS_PLATFORM_MSI);
+	d = irq_find_matching_host(msi_np, DOMAIN_BUS_PLATFORM_MSI, NULL);
 	if (!d)
 		d = irq_find_host(msi_np);
 	dev_set_msi_domain(dev, d);
drivers/pci/of.c +1 -1
index 2e99a50..0da3bce 100644
@@ -80,7 +80,7 @@ struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus)
 	if (!np)
 		np = bus->dev.of_node;
 
-	d = irq_find_matching_host(np, DOMAIN_BUS_PCI_MSI);
+	d = irq_find_matching_host(np, DOMAIN_BUS_PCI_MSI, NULL);
 	if (d)
 		return d;
 
include/linux/irqdomain.h +3 -2
index 4d89f98..12acddb 100644
@@ -178,12 +178,13 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
 					 const struct irq_domain_ops *ops,
 					 void *host_data);
 extern struct irq_domain *irq_find_matching_host(struct device_node *node,
-						 enum irq_domain_bus_token bus_token);
+						 enum irq_domain_bus_token bus_token,
+						 void *bus_data);
 extern void irq_set_default_host(struct irq_domain *host);
 
 static inline struct irq_domain *irq_find_host(struct device_node *node)
 {
-	return irq_find_matching_host(node, DOMAIN_BUS_ANY);
+	return irq_find_matching_host(node, DOMAIN_BUS_ANY, NULL);
 }
 
 /**
kernel/irq/irqdomain.c +4 -2
index 8a8ef31..b4c15af 100644
@@ -190,9 +190,11 @@ EXPORT_SYMBOL_GPL(irq_domain_add_legacy);
  * irq_find_matching_host() - Locates a domain for a given device node
  * @node: device-tree node of the interrupt controller
  * @bus_token: domain-specific data
+ * @bus_data: bus-specific data
  */
 struct irq_domain *irq_find_matching_host(struct device_node *node,
-					  enum irq_domain_bus_token bus_token)
+					  enum irq_domain_bus_token bus_token,
+					  void *bus_data)
 {
 	struct irq_domain *h, *found = NULL;
 	int rc;
@@ -209,7 +211,7 @@ struct irq_domain *irq_find_matching_host(struct device_node *node,
 	mutex_lock(&irq_domain_mutex);
 	list_for_each_entry(h, &irq_domain_list, link) {
 		if (h->ops->match)
-			rc = h->ops->match(h, node, bus_token, NULL);
+			rc = h->ops->match(h, node, bus_token, bus_data);
 		else
 			rc = ((h->of_node != NULL) && (h->of_node == node) &&
 			      ((bus_token == DOMAIN_BUS_ANY) ||
Signature · 1 line
1.9.1
#3 lore raw

PATCH v2 3/12 kernel:irq: Allow for ranked matches on IRQ domains

In reply to [email protected]

From: Jake Oshins <[email protected]>

The existing IRQ domain match code cycles through all the IRQ domains looking for the first one to return a non-zero value from its match() function. There's even a comment that says "this isn't a problem so far..."

This patch changes the semantics on the match() function so that the value returned is a ranking, where zero means "no match." The function now runs the list of IRQ domains twice, finding the highest ranked matches on the first pass and returning the first one of those (to preserve existing behavior, where there might have been multiple matches) on the second pass.

This allows for a situation where a default IRQ domain (specifically the one for message-signaled interrupts on x86 PCs) is always present, but where it can be overriden by an IRQ domain implementation that is targeted at specific PCIe root complexes.

---
 include/linux/irqdomain.h |  2 +-
 kernel/irq/irqdomain.c    | 44 ++++++++++++++++++++++++++++++--------------
 2 files changed, 31 insertions(+), 15 deletions(-)
include/linux/irqdomain.h +1 -1
index 12acddb..2d48deb 100644
@@ -62,7 +62,7 @@ enum irq_domain_bus_token {
 /**
  * struct irq_domain_ops - Methods for irq_domain objects
  * @match: Match an interrupt controller device node to a host, returns
- *         1 on a match
+ *         a ranking (non-zero) on a match
  * @map: Create or update a mapping between a virtual irq number and a hw
  *       irq number. This is called only once for a given mapping.
  * @unmap: Dispose of such a mapping
kernel/irq/irqdomain.c +30 -14

60 lines not on this page · raw message

Signature · 1 line
1.9.1
#4 lore raw

PATCH v2 4/12 drivers:pci: Add IRQ domain lookup by PCI domain

In reply to [email protected]

From: Jake Oshins <[email protected]>

The PCI driver currently looks up IRQ domains for root PCI buses by walking up the Open Firmware tree looking for any that cover this particular PCI root. Since x86 PCs don't implement Open Firmware, this patch offers an alternative lookup by the PCI domain ID (known as "segment" in the PCI and ACPI specs.)

I could have tried to build a (fake) Open Firmware tree and leverage the old code, but I rejected that possibility both because it would have required changes in lots of other places and because most distributions don't even compile in the OF infrastructure when targeting PCs.

---
 drivers/pci/probe.c | 11 +++++++++++
 1 file changed, 11 insertions(+)
drivers/pci/probe.c +11 -0
index 0b2be17..e7e5ff3 100644
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/cpumask.h>
 #include <linux/pci-aspm.h>
+#include <linux/irqdomain.h>
 #include <asm-generic/pci-bridge.h>
 #include "pci.h"
 
@@ -663,12 +664,22 @@ static void pci_set_bus_speed(struct pci_bus *bus)
 static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
 {
 	struct irq_domain *d;
+	int pci_domain;
 
 	/*
 	 * Any firmware interface that can resolve the msi_domain
 	 * should be called from here.
 	 */
 	d = pci_host_bridge_of_msi_domain(bus);
+	if (d)
+		return d;
+
+	/*
+	 * If firmware couldn't help find, it try looking it up by PCI
+	 * domain/segment.
+	 */
+	pci_domain = pci_domain_nr(bus);
+	d = irq_find_matching_host(NULL, DOMAIN_BUS_PCI_MSI, &pci_domain);
 
 	return d;
 }
Signature · 1 line
1.9.1
maintainer
#5 lore raw

Re: [PATCH v2 04/12] drivers:pci: Add IRQ domain lookup by PCI domain

Hi Jake,

I don't know how this will be morphed after Marc's comments, but when you repost this series, please take a look at the existing change history, e.g., with "git log --oneline drivers/pci/probe.c", and make your subject lines follow the existing conventions. In this case, they look like:

PCI: Make pci_msi_setup_pci_dev() non-static for use by arch code
PCI: Set MPS to match upstream bridge
PCI: Move MPS configuration check to pci_configure_device()
PCI: Add pci_scan_root_bus_msi()
PCI: Tolerate hierarchies with no Root Port
...

Bjorn

Quoted 55 lines · On Fri, Sep 11, 2015 at 12:01:03AM +0000, [email protected] wrote:

From: Jake Oshins <[email protected]>

The PCI driver currently looks up IRQ domains for root PCI buses by walking up the Open Firmware tree looking for any that cover this particular PCI root. Since x86 PCs don't implement Open Firmware, this patch offers an alternative lookup by the PCI domain ID (known as "segment" in the PCI and ACPI specs.)

I could have tried to build a (fake) Open Firmware tree and leverage the old code, but I rejected that possibility both because it would have required changes in lots of other places and because most distributions don't even compile in the OF infrastructure when targeting PCs.

---
 drivers/pci/probe.c | 11 +++++++++++
 1 file changed, 11 insertions(+)
drivers/pci/probe.c +11 -0
index 0b2be17..e7e5ff3 100644
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/cpumask.h>
 #include <linux/pci-aspm.h>
+#include <linux/irqdomain.h>
 #include <asm-generic/pci-bridge.h>
 #include "pci.h"
 
@@ -663,12 +664,22 @@ static void pci_set_bus_speed(struct pci_bus *bus)
 static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
 {
 	struct irq_domain *d;
+	int pci_domain;
 
 	/*
 	 * Any firmware interface that can resolve the msi_domain
 	 * should be called from here.
 	 */
 	d = pci_host_bridge_of_msi_domain(bus);
+	if (d)
+		return d;
+
+	/*
+	 * If firmware couldn't help find, it try looking it up by PCI
+	 * domain/segment.
+	 */
+	pci_domain = pci_domain_nr(bus);
+	d = irq_find_matching_host(NULL, DOMAIN_BUS_PCI_MSI, &pci_domain);
 
 	return d;
 }
Signature · 1 line
1.9.1
#6 lore raw

PATCH v2 9/11 kernel:irq: Implement msi match function

In reply to [email protected]

From: Jake Oshins <[email protected]>

Previous patches in this series introduced the concept of ranked matches of IRQ domains, where a default implementation ranks low and a specific implementation might rank higher, overriding the default.

This patch supplies a match function for use by any IRQ domain derived from the default MSI IRQ domain. It returns a rank of '1' when the IRQ domain does not ask for a match based on PCI domain and a rank of '2' if the IRQ domain does set the flag indicating that it wants a more specific match.

At this point in the patch series, there is no implementation of an MSI IRQ domain which asks for a more specific match. That's found in the final patch, introducing a new driver.

---
 include/linux/msi.h |  2 ++
 kernel/irq/msi.c    | 24 ++++++++++++++++++++++++
 2 files changed, 26 insertions(+)
include/linux/msi.h +2 -0
index 7370225..a8ee7a1 100644
@@ -259,6 +259,8 @@ enum {
 	MSI_FLAG_MULTI_PCI_MSI		= (1 << 3),
 	/* Support PCI MSIX interrupts */
 	MSI_FLAG_PCI_MSIX		= (1 << 4),
+	/* Require exact match for PCI domain */
+	MSI_FLAG_PCI_DOMAIN_MATCH	= (1 << 5),
 };
 
 int msi_domain_set_affinity(struct irq_data *data, const struct cpumask *mask,
kernel/irq/msi.c +24 -0
index 7e6512b..5fcd68c 100644
@@ -141,11 +141,35 @@ static void msi_domain_free(struct irq_domain *domain, unsigned int virq,
 	irq_domain_free_irqs_top(domain, virq, nr_irqs);
 }
 
+/*
+ * Return a higher rank for exact matches against PCI domain (segment)
+ * so that generic MSI IRQ domains can be overridden by more specific
+ * implementations.
+ */
+static int msi_domain_match(struct irq_domain *d, struct device_node *node,
+			    enum irq_domain_bus_token bus_token,
+			    void *bus_data)
+{
+	struct msi_domain_info *info = d->host_data;
+
+	if (bus_token != d->bus_token)
+		return 0;
+
+	if (bus_token == DOMAIN_BUS_PCI_MSI) {
+		if (!(info->flags & MSI_FLAG_PCI_DOMAIN_MATCH))
+			return 1;
+		if (bus_data && (info->pci_domain == *(int *)bus_data))
+			return 2;
+	}
+	return 0;
+}
+
 static const struct irq_domain_ops msi_domain_ops = {
 	.alloc		= msi_domain_alloc,
 	.free		= msi_domain_free,
 	.activate	= msi_domain_activate,
 	.deactivate	= msi_domain_deactivate,
+	.match		= msi_domain_match,
 };
 
 #ifdef GENERIC_MSI_DOMAIN_OPS
Signature · 1 line
1.9.1
#7 lore raw

PATCH v2 5/12 drivers:hv: Export a function that maps Linux CPU num onto Hyper-V proc num

In reply to [email protected]

From: Jake Oshins <[email protected]>

This patch exposes the mapping between Linux CPU number and Hyper-V virtual processor number. This is necessary because the hypervisor needs to know which virtual processors to target when making a mapping in the Interrupt Redirection Table in the I/O MMU.

---
 drivers/hv/vmbus_drv.c | 17 +++++++++++++++++
 include/linux/hyperv.h |  2 ++
 2 files changed, 19 insertions(+)
drivers/hv/vmbus_drv.c +17 -0
index f19b6f7..c89d0e5 100644
@@ -1191,6 +1191,23 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
 }
 EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
 
+/**
+ * vmbus_cpu_number_to_vp_number() - Map CPU to VP.
+ * @cpu_number: CPU number in Linux terms
+ *
+ * This function returns the mapping between the Linux processor
+ * number and the hypervisor's virtual processor number, useful
+ * in making hypercalls and such that talk about specific
+ * processors.
+ *
+ * Return: Virtual processor number in Hyper-V terms
+ */
+int vmbus_cpu_number_to_vp_number(int cpu_number)
+{
+	return hv_context.vp_index[cpu_number];
+}
+EXPORT_SYMBOL_GPL(vmbus_cpu_number_to_vp_number);
+
 static int vmbus_acpi_add(struct acpi_device *device)
 {
 	acpi_status result;
include/linux/hyperv.h +2 -0
index 54733d5..02393b6 100644
@@ -982,6 +982,8 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
 			resource_size_t size, resource_size_t align,
 			bool fb_overlap_ok);
 
+int vmbus_cpu_number_to_vp_number(int cpu_number);
+
 /**
  * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
  *
Signature · 1 line
1.9.1
#8 lore raw

PATCH v2 10/11 drivers:hv: Define the channel type for Hyper-V PCI Express pass-through

In reply to [email protected]

From: Jake Oshins <[email protected]>

This defines the channel type for PCI front-ends in Hyper-V VMs.

---
 include/linux/hyperv.h | 11 +++++++++++
 1 file changed, 11 insertions(+)
include/linux/hyperv.h +11 -0
index 033fe59..af0f2e7 100644
@@ -1140,6 +1140,17 @@ u64 do_hypercall(u64 control, void *input, void *output);
 		}
 
 /*
+ * PCI Express Pass Through
+ * {44C4F61D-4444-4400-9D52-802E27EDE19F}
+ */
+
+#define HV_PCIE_GUID \
+	.guid = { \
+			0x1D, 0xF6, 0xC4, 0x44, 0x44, 0x44, 0x00, 0x44, \
+			0x9D, 0x52, 0x80, 0x2E, 0x27, 0xED, 0xE1, 0x9F \
+		}
+
+/*
  * Common header for Hyper-V ICs
  */
 
Signature · 1 line
1.9.1
#9 lore raw

PATCH v2 11/11 drivers:pci:hv: New paravirtual PCI front-end for Hyper-V VMs

In reply to [email protected]

From: Jake Oshins <[email protected]>

This patch introduces a new driver which exposes a root PCI bus whenever a PCI Express device is passed through to a guest VM under Hyper-V. The device can be single- or multi-function. The interrupts for the devices are managed by an IRQ domain, implemented within the driver.

This version incorporates feedback from Thomas Gleixner, Dan Carpenter and Paul Bolle.

---
 MAINTAINERS                    |    1 +
 drivers/pci/Kconfig            |    7 +
 drivers/pci/host/Makefile      |    1 +
 drivers/pci/host/hv_pcifront.c | 2244 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 2253 insertions(+)
 create mode 100644 drivers/pci/host/hv_pcifront.c
MAINTAINERS +1 -0
index 16397bc..6b3f09b 100644
@@ -5011,6 +5011,7 @@ F:	arch/x86/kernel/cpu/mshyperv.c
 F:	drivers/hid/hid-hyperv.c
 F:	drivers/hv/
 F:	drivers/input/serio/hyperv-keyboard.c
+F:	drivers/pci/host/hv_pcifront.c
 F:	drivers/net/hyperv/
 F:	drivers/scsi/storvsc_drv.c
 F:	drivers/video/fbdev/hyperv_fb.c
drivers/pci/Kconfig +7 -0
index 73de4ef..9b82d93 100644
@@ -118,4 +118,11 @@ config PCI_LABEL
 	def_bool y if (DMI || ACPI)
 	select NLS
 
+config HYPERV_VPCI
+        tristate "Hyper-V PCI Frontend"
+        depends on PCI && X86 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN
+        help
+          The PCI device frontend driver allows the kernel to import arbitrary
+          PCI devices from a PCI backend to support PCI driver domains.
+
 source "drivers/pci/host/Kconfig"
drivers/pci/host/Makefile +1 -0
index 140d66f..39581fb 100644
@@ -2,6 +2,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
+obj-$(CONFIG_HYPERV_VPCI) += hv_pcifront.o
 obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
 obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
 obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
drivers/pci/host/hv_pcifront.c new file +2244 -0

2,244 lines not on this page · raw message

Signature · 1 line
1.9.1
#10 lore raw

PATCH v2 6/12 drivers:hv: Export do_hypercall()

In reply to [email protected]

From: Jake Oshins <[email protected]>

This patch exposes the function that hv_vmbus.ko uses to make hypercalls. This is necessary for retargeting an interrupt when it is given a new affinity.

---
 drivers/hv/hv.c        | 3 ++-
 include/linux/hyperv.h | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)
drivers/hv/hv.c +2 -1
index 6341be8..6d01649 100644
@@ -91,7 +91,7 @@ static int query_hypervisor_info(void)
 /*
  * do_hypercall- Invoke the specified hypercall
  */
-static u64 do_hypercall(u64 control, void *input, void *output)
+u64 do_hypercall(u64 control, void *input, void *output)
 {
 	u64 input_address = (input) ? virt_to_phys(input) : 0;
 	u64 output_address = (output) ? virt_to_phys(output) : 0;
@@ -132,6 +132,7 @@ static u64 do_hypercall(u64 control, void *input, void *output)
 	return hv_status_lo | ((u64)hv_status_hi << 32);
 #endif /* !x86_64 */
 }
+EXPORT_SYMBOL_GPL(do_hypercall);
 
 #ifdef CONFIG_X86_64
 static cycle_t read_hv_clock_tsc(struct clocksource *arg)
include/linux/hyperv.h +1 -0
index 02393b6..033fe59 100644
@@ -983,6 +983,7 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
 			bool fb_overlap_ok);
 
 int vmbus_cpu_number_to_vp_number(int cpu_number);
+u64 do_hypercall(u64 control, void *input, void *output);
 
 /**
  * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
Signature · 1 line
1.9.1
#11 lore raw

RE: [PATCH v2 06/12] drivers:hv: Export do_hypercall()

Quoted 29 lines

-----Original Message-----
From: [email protected] [mailto:[email protected]]
Sent: Thursday, September 10, 2015 5:01 PM
To: [email protected]; KY Srinivasan <[email protected]>; linux- [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
Cc: Jake Oshins <[email protected]>
Subject: [PATCH v2 06/12] drivers:hv: Export do_hypercall()

From: Jake Oshins <[email protected]>

This patch exposes the function that hv_vmbus.ko uses to make hypercalls. This
is necessary for retargeting an interrupt when it is given a new affinity.

---
 drivers/hv/hv.c        | 3 ++-
 include/linux/hyperv.h | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)
drivers/hv/hv.c +0 -0
index 6341be8..6d01649 100644

drivers/hv/hv.c static int query_hypervisor_info(void) · line 94

Quoted 5 lines
drivers/hv/hv.c +1 -1
@@ -91,7 +91,7 @@ static int query_hypervisor_info(void)
 /*
  * do_hypercall- Invoke the specified hypercall
  */
-static u64 do_hypercall(u64 control, void *input, void *output)
+u64 do_hypercall(u64 control, void *input, void *output)

do_hypercall() is not an appropriate name for a function to be exported. I plan to take the base vmbus patches through Greg's tree and if it is ok with you, I will change the name of this function.

Regards,

K. Y

#12 lore raw

RE: [PATCH v2 06/12] drivers:hv: Export do_hypercall()

Quoted 13 lines

drivers/hv/hv.c static int query_hypervisor_info(void) · line 94

Quoted 7 lines

---

drivers/hv/hv.c +1 -1
@@ -91,7 +91,7 @@ static int query_hypervisor_info(void)
 /*
  * do_hypercall- Invoke the specified hypercall
  */
-static u64 do_hypercall(u64 control, void *input, void *output)
+u64 do_hypercall(u64 control, void *input, void *output)

do_hypercall() is not an appropriate name for a function to be exported. I plan to take the base
vmbus patches through Greg's tree and if it is ok with you, I will change the name of this function.

Quoted 3 lines

Regards,

K. Y

Of course. Thanks.

-- Jake Oshins

#13 lore raw

PATCH v2 7/12 drivers:x86:pci: Make it possible to implement a PCI MSI IRQ Domain in a module.

In reply to [email protected]

From: Jake Oshins <[email protected]>

The Linux kernel already has the concept of IRQ domain, wherein a component can expose a set of IRQs which are managed by a particular interrupt controller chip or other subsystem. The PCI driver exposes the notion of an IRQ domain for Message-Signaled Interrupts (MSI) from PCI Express devices. This patch exposes the functions which are necessary for making an MSI IRQ domain within a module.

The same goal could be accomplished by building an MSI IRQ domain for Hyper-V into the kernel itself, but this would have required pulling in a lot of other code which currently exists in modules, and it seemed cleaner to avoid that.

---
 arch/x86/include/asm/msi.h    | 4 ++++
 arch/x86/kernel/apic/msi.c    | 5 +++--
 arch/x86/kernel/apic/vector.c | 2 ++
 drivers/pci/msi.c             | 2 ++
 kernel/irq/chip.c             | 1 +
 5 files changed, 12 insertions(+), 2 deletions(-)
arch/x86/include/asm/msi.h +4 -0
index 93724cc..e8b7924 100644
@@ -1,7 +1,11 @@
 #ifndef _ASM_X86_MSI_H
 #define _ASM_X86_MSI_H
 #include <asm/hw_irq.h>
+#include <asm/irqdomain.h>
 
 typedef struct irq_alloc_info msi_alloc_info_t;
 
+int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
+		    msi_alloc_info_t *arg);
+
 #endif /* _ASM_X86_MSI_H */
arch/x86/kernel/apic/msi.c +3 -2
index 5f1feb6..bdb28fc 100644
@@ -96,8 +96,8 @@ static irq_hw_number_t pci_msi_get_hwirq(struct msi_domain_info *info,
 	return arg->msi_hwirq;
 }
 
-static int pci_msi_prepare(struct irq_domain *domain, struct device *dev,
-			   int nvec, msi_alloc_info_t *arg)
+int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
+		    msi_alloc_info_t *arg)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct msi_desc *desc = first_pci_msi_entry(pdev);
@@ -113,6 +113,7 @@ static int pci_msi_prepare(struct irq_domain *domain, struct device *dev,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(pci_msi_prepare);
 
 static void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
 {
arch/x86/kernel/apic/vector.c +2 -0
index 1bbd0fe..b16d915 100644
@@ -29,6 +29,7 @@ struct apic_chip_data {
 };
 
 struct irq_domain *x86_vector_domain;
+EXPORT_SYMBOL_GPL(x86_vector_domain);
 static DEFINE_RAW_SPINLOCK(vector_lock);
 static cpumask_var_t vector_cpumask;
 static struct irq_chip lapic_controller;
@@ -66,6 +67,7 @@ struct irq_cfg *irqd_cfg(struct irq_data *irq_data)
 
 	return data ? &data->cfg : NULL;
 }
+EXPORT_SYMBOL_GPL(irqd_cfg);
 
 struct irq_cfg *irq_cfg(unsigned int irq)
 {
drivers/pci/msi.c +2 -0
index c7ad8ce..1aaa26d 100644
@@ -1119,6 +1119,7 @@ struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc)
 {
 	return to_pci_dev(desc->dev);
 }
+EXPORT_SYMBOL(msi_desc_to_pci_dev);
 
 void *msi_desc_to_pci_sysdata(struct msi_desc *desc)
 {
@@ -1274,6 +1275,7 @@ struct irq_domain *pci_msi_create_irq_domain(struct device_node *node,
 	domain->bus_token = DOMAIN_BUS_PCI_MSI;
 	return domain;
 }
+EXPORT_SYMBOL_GPL(pci_msi_create_irq_domain);
 
 /**
  * pci_msi_domain_alloc_irqs - Allocate interrupts for @dev in @domain
kernel/irq/chip.c +1 -0
index 6e40a95..b0d9ecd 100644
@@ -935,6 +935,7 @@ void irq_chip_ack_parent(struct irq_data *data)
 	data = data->parent_data;
 	data->chip->irq_ack(data);
 }
+EXPORT_SYMBOL_GPL(irq_chip_ack_parent);
 
 /**
  * irq_chip_mask_parent - Mask the parent interrupt
Signature · 1 line
1.9.1
#14 lore raw

PATCH v2 8/12 drivers:pci:msi: Store PCI domain (segment) as part of IRQ domain

In reply to [email protected]

From: Jake Oshins <[email protected]>

In order to allow an MSI IRQ domain to be specific to a PCI domain, add a field to the struct that tracks the PCI domain.

---
 include/linux/msi.h | 2 ++
 1 file changed, 2 insertions(+)
include/linux/msi.h +2 -0
index ad939d0..7370225 100644
@@ -227,6 +227,7 @@ struct msi_domain_ops {
  * @handler_data:	Optional: associated interrupt flow handler data
  * @handler_name:	Optional: associated interrupt flow handler name
  * @data:		Optional: domain specific data
+ * @pci_domain:		Associated PCI domain (segment)
  */
 struct msi_domain_info {
 	u32			flags;
@@ -237,6 +238,7 @@ struct msi_domain_info {
 	void			*handler_data;
 	const char		*handler_name;
 	void			*data;
+	int			pci_domain;
 };
 
 /* Flags for msi_domain_info */
Signature · 1 line
1.9.1
#15 lore raw
In reply to [email protected]

Hi Jake,

In the future, please CC me on anything that touches irqdomains, along with Jiang Liu as we both co-maintain this piece of code.

Quoted 11 lines · On 11/09/15 01:00, [email protected] wrote:

From: Jake Oshins <[email protected]>

The patch series updates the one sent about a month ago in three ways. It integrated with other IRQ domain work done in linux-next in that time, it distributes interrupts to multiple virtual processors in the guest VM, and it incorporates feedback from Thomas Gleixner and others.

These patches change the IRQ domain code so that an IRQ domain can match on both bus type and on the PCI domain. The IRQ domain match code is modified so that IRQ domains can have a "rank," allowing for a default one which matches every x86 PC and more specific ones that replace the default.

I'm not really fond of this approach. We already have a way to match an IRQ domain, and that's the device node. It looks to me that you're going through a lot of pain inventing a new infrastructure to avoid divorcing the two. If you could lookup your PCI IRQ domain directly based some (non-DT) identifier, and then possibly fallback to the default one, would that help?

If so, here's the deal: I have been working on a patch series that addresses the above for unrelated reasons (ACPI support on arm64). It has been posted twice already:

http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/358768.html

and the latest version is there:

https://git.kernel.org/cgit/linux/kernel/git/maz/arm-platforms.git/log/?h=irq/gsi-irq-domain-v3

I have the feeling that you could replace a lot of your patches with this infrastructure.

Thoughts?

	M.
Signature · 1 line
Jazz is not dead. It just smells funny...
#16 lore raw
Quoted 11 lines

-----Original Message-----
From: Marc Zyngier [mailto:[email protected]]
Sent: Monday, September 14, 2015 8:01 AM
To: Jake Oshins <[email protected]>; [email protected]; KY Srinivasan <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Jiang Liu <[email protected]>
Subject: Re: [PATCH v2 00/12] New paravirtual PCI front-end for Hyper-V VMs

Quoted 5 lines

Hi Jake,

In the future, please CC me on anything that touches irqdomains, along with Jiang Liu as we both co-maintain this piece of code.

Absolutely. Sorry for that omission.

Quoted 34 lines · On 11/09/15 01:00, [email protected] wrote:
Quoted 8 lines

From: Jake Oshins <[email protected]>

The patch series updates the one sent about a month ago in three ways. It integrated with other IRQ domain work done in linux-next in that time, it distributes interrupts to multiple virtual processors in the guest VM, and it incorporates feedback from Thomas Gleixner and others.

These patches change the IRQ domain code so that an IRQ domain can

match on both

Quoted 1 line

bus type and on the PCI domain. The IRQ domain match code is modified

so that

Quoted 1 line

IRQ domains can have a "rank," allowing for a default one which matches

every

Quoted 1 line

x86 PC and more specific ones that replace the default.

I'm not really fond of this approach. We already have a way to match an IRQ domain, and that's the device node. It looks to me that you're going through a lot of pain inventing a new infrastructure to avoid divorcing the two. If you could lookup your PCI IRQ domain directly based some (non-DT) identifier, and then possibly fallback to the default one, would that help?

If so, here's the deal: I have been working on a patch series that addresses the above for unrelated reasons (ACPI support on arm64). It has been posted twice already:

http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/358768.html

and the latest version is there:

https://git.kernel.org/cgit/linux/kernel/git/maz/arm-
platforms.git/log/?h=irq/gsi-irq-domain-v3

Quoted 7 lines

I have the feeling that you could replace a lot of your patches with this infrastructure.

Thoughts?

	M.

--

First, thank you so much for reviewing this. I've read the patch series above, but I'm sure that I might have misinterpreted it. It seems to merge the DT and ACPI GSI infrastructure, which I think is a great idea. I'm not sure, however, that it would, as it stands, provide what I need here. Please do tell me if I'm wrong.

The series above allows you to supply different IRQ domains for separate parts of the ACPI GSI space, which is fine for IRQs which are actually defined by ACPI. Message-signaled interrupts (MSI), however, aren't defined by ACPI. ACPI only talks about the routing of interrupts with pins and traces (or ones which have equivalent mechanisms like the INTx# protocol in PCI Express.)

What the older DT layer code allowed was for the PCI driver to look up an IRQ domain by walking up the device tree looking for a node that claimed to be an IRQ domain. The match() function on the IRQ domain allowed it to say that it supported interrupts on PCI buses.

What's not clear to me is how I would create an IRQ domain that matches not on ACPI GSI ranges (because ACPI doesn't talk about MSI) and not just on generic PCI buses. I need to be able to ask for an IRQ domain "from my parent" which doesn't really exist without the OF device tree or "for a specific PCI bus domain." That second one is what I was trying to enable.

Is there a way to do that with the infrastructure that you're introducing?

Thanks again,
Jake Oshins

#17 lore raw
Quoted 86 lines · Jake Oshins
Quoted 11 lines

-----Original Message-----
From: Marc Zyngier [mailto:[email protected]]
Sent: Monday, September 14, 2015 8:01 AM
To: Jake Oshins <[email protected]>; [email protected]; KY Srinivasan <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Jiang Liu <[email protected]>
Subject: Re: [PATCH v2 00/12] New paravirtual PCI front-end for Hyper-V VMs

Quoted 5 lines

Hi Jake,

In the future, please CC me on anything that touches irqdomains, along with Jiang Liu as we both co-maintain this piece of code.

Absolutely. Sorry for that omission.

Quoted 34 lines · On 11/09/15 01:00, [email protected] wrote:
Quoted 8 lines

From: Jake Oshins <[email protected]>

The patch series updates the one sent about a month ago in three ways. It integrated with other IRQ domain work done in linux-next in that time, it distributes interrupts to multiple virtual processors in the guest VM, and it incorporates feedback from Thomas Gleixner and others.

These patches change the IRQ domain code so that an IRQ domain can

match on both

Quoted 1 line

bus type and on the PCI domain. The IRQ domain match code is modified

so that

Quoted 1 line

IRQ domains can have a "rank," allowing for a default one which matches

every

Quoted 1 line

x86 PC and more specific ones that replace the default.

I'm not really fond of this approach. We already have a way to match an IRQ domain, and that's the device node. It looks to me that you're going through a lot of pain inventing a new infrastructure to avoid divorcing the two. If you could lookup your PCI IRQ domain directly based some (non-DT) identifier, and then possibly fallback to the default one, would that help?

If so, here's the deal: I have been working on a patch series that addresses the above for unrelated reasons (ACPI support on arm64). It has been posted twice already:

http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/358768.html

and the latest version is there:

https://git.kernel.org/cgit/linux/kernel/git/maz/arm-
platforms.git/log/?h=irq/gsi-irq-domain-v3

Quoted 7 lines

I have the feeling that you could replace a lot of your patches with this infrastructure.

Thoughts?

	M.

--

First, thank you so much for reviewing this. I've read the patch series above, but I'm sure that I might have misinterpreted it. It seems to merge the DT and ACPI GSI infrastructure, which I think is a great idea. I'm not sure, however, that it would, as it stands, provide what I need here. Please do tell me if I'm wrong.

The series above allows you to supply different IRQ domains for separate parts of the ACPI GSI space, which is fine for IRQs which are actually defined by ACPI. Message-signaled interrupts (MSI), however, aren't defined by ACPI. ACPI only talks about the routing of interrupts with pins and traces (or ones which have equivalent mechanisms like the INTx# protocol in PCI Express.)

What the older DT layer code allowed was for the PCI driver to look up an IRQ domain by walking up the device tree looking for a node that claimed to be an IRQ domain. The match() function on the IRQ domain allowed it to say that it supported interrupts on PCI buses.

What's not clear to me is how I would create an IRQ domain that matches not on ACPI GSI ranges (because ACPI doesn't talk about MSI) and not just on generic PCI buses. I need to be able to ask for an IRQ domain "from my parent" which doesn't really exist without the OF device tree or "for a specific PCI bus domain." That second one is what I was trying to enable.

Quoted 2 lines

Is there a way to do that with the infrastructure that you're introducing?

The ACPI/GSI stuff is a red herring, and is completely unrelated to the problem you're trying to solve. What I think is of interest to you is contained in the first three patches.

In your 4th patch, you have the following code:

+ pci_domain = pci_domain_nr(bus);
+ d = irq_find_matching_host(NULL, DOMAIN_BUS_PCI_MSI, &pci_domain);

which really feels like you're trying to create a namespace that is parallel to the one defined by the device_node parameter. What I'm trying to do is to be able to replace the device_node by something more generic (at the moment, you can either pass a device_node or some token that the irqdomain subsystem generates for you - see patch #7 for an example).

You could pass this token to pci_msi_create_irq_domain (which obviously needs some repainting not to take a device_node), store it in your bus structure, and perform the lookup based on this value. Or store the actual domain there, whatever.

What I want to do is really to make this device_node pointer for systems that do not have a DT node to pass there, which is exactly your case (by the look of it, the bus number is your identifier of choice, but I suspect a pointer to an internal structure would be better suited).

	M.
Signature · 1 line
Jazz is not dead. It just smells funny...
#18 lore raw
Quoted 39 lines

-----Original Message-----
From: Marc Zyngier [mailto:[email protected]]
Sent: Tuesday, September 15, 2015 2:57 AM
To: Jake Oshins <[email protected]>; [email protected]; KY Srinivasan <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Jiang Liu <[email protected]>
Subject: Re: [PATCH v2 00/12] New paravirtual PCI front-end for Hyper-V VMs

Quoted 3 lines

Is there a way to do that with the infrastructure that you're introducing?

The ACPI/GSI stuff is a red herring, and is completely unrelated to the problem you're trying to solve. What I think is of interest to you is contained in the first three patches.

In your 4th patch, you have the following code:

(quoted diff) +2 -0
+	pci_domain = pci_domain_nr(bus);
+	d = irq_find_matching_host(NULL, DOMAIN_BUS_PCI_MSI,

&pci_domain);

which really feels like you're trying to create a namespace that is parallel to the one defined by the device_node parameter. What I'm trying to do is to be able to replace the device_node by something more generic (at the moment, you can either pass a device_node or some token that the irqdomain subsystem generates for you - see patch #7 for an example).

You could pass this token to pci_msi_create_irq_domain (which obviously needs some repainting not to take a device_node), store it in your bus structure, and perform the lookup based on this value. Or store the actual domain there, whatever.

Quoted 7 lines

What I want to do is really to make this device_node pointer for systems that do not have a DT node to pass there, which is exactly your case (by the look of it, the bus number is your identifier of choice, but I suspect a pointer to an internal structure would be better suited).

	M.

--

Got it. I'll rebase on your changes and send this series again, using the strategy that you outline here. I may wait a little while until your patches make it into linux-next.

Thanks again,
Jake Oshins