Skip to contentSkip to conversation

PCI: Record an fwnode associated with root PCI buses, optionally

PATCH In review [email protected] 3 participants 13 messages Oct 26, 2015 – Oct 28, 2015 2 messages not in the archive

Subsystems (6)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw

PATCH v3 4/7 PCI: Record an fwnode associated with root PCI buses, optionally

From: Jake Oshins <[email protected]>

This patch allows a PCI front-end implementation to supply an fwnode_handle associated with a root PCI bus, optionally. If supplied, the PCI driver records this.

This patch supports the next patch in the series, which looks up an IRQ domain through this handle.

---
 arch/sparc/kernel/pci.c       | 2 +-
 drivers/acpi/pci_root.c       | 2 +-
 drivers/parisc/lba_pci.c      | 2 +-
 drivers/pci/host/pci-xgene.c  | 2 +-
 drivers/pci/host/pcie-iproc.c | 3 ++-
 drivers/pci/probe.c           | 8 +++++---
 include/linux/pci.h           | 4 +++-
 7 files changed, 14 insertions(+), 9 deletions(-)
arch/sparc/kernel/pci.c +1 -1
index b91d7f1..3d4e9f9 100644
@@ -660,7 +660,7 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
 	pbm->busn.flags	= IORESOURCE_BUS;
 	pci_add_resource(&resources, &pbm->busn);
 	bus = pci_create_root_bus(parent, pbm->pci_first_busno, pbm->pci_ops,
-				  pbm, &resources);
+				  pbm, &resources, NULL);
 	if (!bus) {
 		printk(KERN_ERR "Failed to create bus for %s\n",
 		       node->full_name);
drivers/acpi/pci_root.c +1 -1
index 850d7bf..eab95bc 100644
@@ -840,7 +840,7 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 	pci_acpi_root_add_resources(info);
 	pci_add_resource(&info->resources, &root->secondary);
 	bus = pci_create_root_bus(NULL, busnum, ops->pci_ops,
-				  sysdata, &info->resources);
+				  sysdata, &info->resources, NULL);
 	if (!bus)
 		goto out_release_info;
 
drivers/parisc/lba_pci.c +1 -1
index a32c1f6..a7b9d5c 100644
@@ -1567,7 +1567,7 @@ lba_driver_probe(struct parisc_device *dev)
 	dev->dev.platform_data = lba_dev;
 	lba_bus = lba_dev->hba.hba_bus =
 		pci_create_root_bus(&dev->dev, lba_dev->hba.bus_num.start,
-				    cfg_ops, NULL, &resources);
+				    cfg_ops, NULL, &resources, NULL);
 	if (!lba_bus) {
 		pci_free_resource_list(&resources);
 		return 0;
drivers/pci/host/pci-xgene.c +1 -1
index ae00ce2..95c20c8 100644
@@ -545,7 +545,7 @@ static int xgene_pcie_probe_bridge(struct platform_device *pdev)
 		return ret;
 
 	bus = pci_create_root_bus(&pdev->dev, 0,
-					&xgene_pcie_ops, port, &res);
+					&xgene_pcie_ops, port, &res, NULL);
 	if (!bus)
 		return -ENOMEM;
 
drivers/pci/host/pcie-iproc.c +2 -1
index 9193951..bc999b7 100644
@@ -357,7 +357,8 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
 	sysdata = pcie;
 #endif
 
-	bus = pci_create_root_bus(pcie->dev, 0, &iproc_pcie_ops, sysdata, res);
+	bus = pci_create_root_bus(pcie->dev, 0, &iproc_pcie_ops, sysdata, res,
+				  NULL);
 	if (!bus) {
 		dev_err(pcie->dev, "unable to create PCI root bus\n");
 		ret = -ENOMEM;
drivers/pci/probe.c +5 -3
index f441d1b..c0f2e44 100644
@@ -2039,7 +2039,8 @@ void __weak pcibios_remove_bus(struct pci_bus *bus)
 }
 
 struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
-		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+		struct pci_ops *ops, void *sysdata, struct list_head *resources,
+		struct fwnode_handle *fwnode)
 {
 	int error;
 	struct pci_host_bridge *bridge;
@@ -2069,6 +2070,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 	if (!bridge)
 		goto err_out;
 
+	bridge->fwnode = fwnode;
 	bridge->dev.parent = parent;
 	bridge->dev.release = pci_release_host_bridge_dev;
 	dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
@@ -2223,7 +2225,7 @@ struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus,
 			break;
 		}
 
-	b = pci_create_root_bus(parent, bus, ops, sysdata, resources);
+	b = pci_create_root_bus(parent, bus, ops, sysdata, resources, NULL);
 	if (!b)
 		return NULL;
 
@@ -2261,7 +2263,7 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
 	pci_add_resource(&resources, &ioport_resource);
 	pci_add_resource(&resources, &iomem_resource);
 	pci_add_resource(&resources, &busn_resource);
-	b = pci_create_root_bus(NULL, bus, ops, sysdata, &resources);
+	b = pci_create_root_bus(NULL, bus, ops, sysdata, &resources, NULL);
 	if (b) {
 		pci_scan_child_bus(b);
 	} else {
include/linux/pci.h +3 -1
index b54fbf1..86ce5fa 100644
@@ -409,6 +409,7 @@ struct pci_host_bridge {
 	struct device dev;
 	struct pci_bus *bus;		/* root bus */
 	struct list_head windows;	/* resource_entry */
+	struct fwnode_handle *fwnode;
 	void (*release_fn)(struct pci_host_bridge *);
 	void *release_data;
 	unsigned int ignore_reset_delay:1;	/* for entire hierarchy */
@@ -789,7 +790,8 @@ void pci_bus_add_devices(const struct pci_bus *bus);
 struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata);
 struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 				    struct pci_ops *ops, void *sysdata,
-				    struct list_head *resources);
+				    struct list_head *resources,
+				    struct fwnode_handle *fwnode);
 int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax);
 int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax);
 void pci_bus_release_busn_res(struct pci_bus *b);
Signature · 1 line
1.9.1
#2 lore raw
reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree…

Hi Jake,

[auto build test ERROR on next-20151022 -- if it's inappropriate base, please suggest rules for selecting the more suitable base]

url:    https://github.com/0day-ci/linux/commits/jakeo-microsoft-com/New-paravirtual-PCI-front-end-for-Hyper-V-VMs/20151027-072118
config: parisc-b180_defconfig (attached as .config)

reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=parisc

All errors (new ones prefixed by >>):

drivers/parisc/dino.c: In function 'dino_probe':

>> drivers/parisc/dino.c:988:32: error: too few arguments to function 'pci_create_root_bus'
     dino_dev->hba.hba_bus = bus = pci_create_root_bus(&dev->dev,
                                   ^

In file included from drivers/parisc/dino.c:49:0:
include/linux/pci.h:791:17: note: declared here
struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
^

vim +/pci_create_root_bus +988 drivers/parisc/dino.c

30aa80da Yinghai Lu     2012-05-17  982  	dino_dev->hba.bus_num.flags = IORESOURCE_BUS;
30aa80da Yinghai Lu     2012-05-17  983  	pci_add_resource(&resources, &dino_dev->hba.bus_num);
^1da177e Linus Torvalds 2005-04-16  984  	/*
^1da177e Linus Torvalds 2005-04-16  985  	** It's not used to avoid chicken/egg problems
^1da177e Linus Torvalds 2005-04-16  986  	** with configuration accessor functions.
^1da177e Linus Torvalds 2005-04-16  987  	*/
7590e500 Bjorn Helgaas  2011-10-28 @988  	dino_dev->hba.hba_bus = bus = pci_create_root_bus(&dev->dev,
7590e500 Bjorn Helgaas  2011-10-28  989  			 dino_current_bus, &dino_cfg_ops, NULL, &resources);
c4e06576 Bjorn Helgaas  2011-10-28  990  	if (!bus) {
c4e06576 Bjorn Helgaas  2011-10-28  991  		printk(KERN_ERR "ERROR: failed to scan PCI bus on %s (duplicate bus number %d?)\n",

:::::: The code at line 988 was first introduced by commit
:::::: 7590e500ad83d9ac1e55eed4720e053eff14b8e5 parisc/PCI: dino: convert to pci_create_root_bus() for correct root bus resources

:::::: TO: Bjorn Helgaas <[email protected]> :::::: CC: Jesse Barnes <[email protected]>

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation

#3 lore raw
In reply to [email protected]
reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree…

Hi Jake,

[auto build test ERROR on next-20151022 -- if it's inappropriate base, please suggest rules for selecting the more suitable base]

url:    https://github.com/0day-ci/linux/commits/jakeo-microsoft-com/New-paravirtual-PCI-front-end-for-Hyper-V-VMs/20151027-072118
config: powerpc-defconfig (attached as .config)

reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=powerpc

All errors (new ones prefixed by >>):

arch/powerpc/kernel/pci-common.c: In function 'pcibios_scan_phb':

>> arch/powerpc/kernel/pci-common.c:1621:8: error: too few arguments to function 'pci_create_root_bus'
     bus = pci_create_root_bus(hose->parent, hose->first_busno,
           ^

In file included from arch/powerpc/kernel/pci-common.c:20:0:
include/linux/pci.h:791:17: note: declared here
struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
^

vim +/pci_create_root_bus +1621 arch/powerpc/kernel/pci-common.c

be8e60d8 Yinghai Lu    2012-05-17  1615  	hose->busn.start = hose->first_busno;
be8e60d8 Yinghai Lu    2012-05-17  1616  	hose->busn.end	 = hose->last_busno;
be8e60d8 Yinghai Lu    2012-05-17  1617  	hose->busn.flags = IORESOURCE_BUS;
be8e60d8 Yinghai Lu    2012-05-17  1618  	pci_add_resource(&resources, &hose->busn);
be8e60d8 Yinghai Lu    2012-05-17  1619  
0ed2c722 Grant Likely  2009-08-28  1620  	/* Create an empty bus for the toplevel */
45a709f8 Bjorn Helgaas 2011-10-28 @1621  	bus = pci_create_root_bus(hose->parent, hose->first_busno,
45a709f8 Bjorn Helgaas 2011-10-28  1622  				  hose->ops, hose, &resources);
0ed2c722 Grant Likely  2009-08-28  1623  	if (bus == NULL) {
0ed2c722 Grant Likely  2009-08-28  1624  		pr_err("Failed to create bus for PCI domain %04x\n",

:::::: The code at line 1621 was first introduced by commit
:::::: 45a709f890a7b84930942a5f5f82011312fe727c powerpc/PCI: convert to pci_create_root_bus()

:::::: TO: Bjorn Helgaas <[email protected]> :::::: CC: Jesse Barnes <[email protected]>

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation

#4 lore raw
In reply to [email protected]
Quoted 8 lines · On 2015/10/27 7:15, [email protected] wrote:

From: Jake Oshins <[email protected]>

This patch allows a PCI front-end implementation to supply an fwnode_handle associated with a root PCI bus, optionally. If supplied, the PCI driver records this.

This patch supports the next patch in the series, which looks up an IRQ domain through this handle.

Hi JaKeo,
Instead of changing the pci_create_root_bus() interface,
how about packing fwnode into sysdata, then we may either 1) introduce a helper to retrieve fwnode from sysdata or 2) set host_bridge->fwnode = sysdata in function pcibios_root_bridge_prepare.

Thanks,
Gerry

Quoted 141 lines
---
 arch/sparc/kernel/pci.c       | 2 +-
 drivers/acpi/pci_root.c       | 2 +-
 drivers/parisc/lba_pci.c      | 2 +-
 drivers/pci/host/pci-xgene.c  | 2 +-
 drivers/pci/host/pcie-iproc.c | 3 ++-
 drivers/pci/probe.c           | 8 +++++---
 include/linux/pci.h           | 4 +++-
 7 files changed, 14 insertions(+), 9 deletions(-)
arch/sparc/kernel/pci.c +1 -1
index b91d7f1..3d4e9f9 100644
@@ -660,7 +660,7 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
 	pbm->busn.flags	= IORESOURCE_BUS;
 	pci_add_resource(&resources, &pbm->busn);
 	bus = pci_create_root_bus(parent, pbm->pci_first_busno, pbm->pci_ops,
-				  pbm, &resources);
+				  pbm, &resources, NULL);
 	if (!bus) {
 		printk(KERN_ERR "Failed to create bus for %s\n",
 		       node->full_name);
drivers/acpi/pci_root.c +1 -1
index 850d7bf..eab95bc 100644
@@ -840,7 +840,7 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 	pci_acpi_root_add_resources(info);
 	pci_add_resource(&info->resources, &root->secondary);
 	bus = pci_create_root_bus(NULL, busnum, ops->pci_ops,
-				  sysdata, &info->resources);
+				  sysdata, &info->resources, NULL);
 	if (!bus)
 		goto out_release_info;
 
drivers/parisc/lba_pci.c +1 -1
index a32c1f6..a7b9d5c 100644
@@ -1567,7 +1567,7 @@ lba_driver_probe(struct parisc_device *dev)
 	dev->dev.platform_data = lba_dev;
 	lba_bus = lba_dev->hba.hba_bus =
 		pci_create_root_bus(&dev->dev, lba_dev->hba.bus_num.start,
-				    cfg_ops, NULL, &resources);
+				    cfg_ops, NULL, &resources, NULL);
 	if (!lba_bus) {
 		pci_free_resource_list(&resources);
 		return 0;
drivers/pci/host/pci-xgene.c +1 -1
index ae00ce2..95c20c8 100644
@@ -545,7 +545,7 @@ static int xgene_pcie_probe_bridge(struct platform_device *pdev)
 		return ret;
 
 	bus = pci_create_root_bus(&pdev->dev, 0,
-					&xgene_pcie_ops, port, &res);
+					&xgene_pcie_ops, port, &res, NULL);
 	if (!bus)
 		return -ENOMEM;
 
drivers/pci/host/pcie-iproc.c +2 -1
index 9193951..bc999b7 100644
@@ -357,7 +357,8 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
 	sysdata = pcie;
 #endif
 
-	bus = pci_create_root_bus(pcie->dev, 0, &iproc_pcie_ops, sysdata, res);
+	bus = pci_create_root_bus(pcie->dev, 0, &iproc_pcie_ops, sysdata, res,
+				  NULL);
 	if (!bus) {
 		dev_err(pcie->dev, "unable to create PCI root bus\n");
 		ret = -ENOMEM;
drivers/pci/probe.c +5 -3
index f441d1b..c0f2e44 100644
@@ -2039,7 +2039,8 @@ void __weak pcibios_remove_bus(struct pci_bus *bus)
 }
 
 struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
-		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+		struct pci_ops *ops, void *sysdata, struct list_head *resources,
+		struct fwnode_handle *fwnode)
 {
 	int error;
 	struct pci_host_bridge *bridge;
@@ -2069,6 +2070,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 	if (!bridge)
 		goto err_out;
 
+	bridge->fwnode = fwnode;
 	bridge->dev.parent = parent;
 	bridge->dev.release = pci_release_host_bridge_dev;
 	dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
@@ -2223,7 +2225,7 @@ struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus,
 			break;
 		}
 
-	b = pci_create_root_bus(parent, bus, ops, sysdata, resources);
+	b = pci_create_root_bus(parent, bus, ops, sysdata, resources, NULL);
 	if (!b)
 		return NULL;
 
@@ -2261,7 +2263,7 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
 	pci_add_resource(&resources, &ioport_resource);
 	pci_add_resource(&resources, &iomem_resource);
 	pci_add_resource(&resources, &busn_resource);
-	b = pci_create_root_bus(NULL, bus, ops, sysdata, &resources);
+	b = pci_create_root_bus(NULL, bus, ops, sysdata, &resources, NULL);
 	if (b) {
 		pci_scan_child_bus(b);
 	} else {
include/linux/pci.h +3 -1
index b54fbf1..86ce5fa 100644
@@ -409,6 +409,7 @@ struct pci_host_bridge {
 	struct device dev;
 	struct pci_bus *bus;		/* root bus */
 	struct list_head windows;	/* resource_entry */
+	struct fwnode_handle *fwnode;
 	void (*release_fn)(struct pci_host_bridge *);
 	void *release_data;
 	unsigned int ignore_reset_delay:1;	/* for entire hierarchy */
@@ -789,7 +790,8 @@ void pci_bus_add_devices(const struct pci_bus *bus);
 struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata);
 struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 				    struct pci_ops *ops, void *sysdata,
-				    struct list_head *resources);
+				    struct list_head *resources,
+				    struct fwnode_handle *fwnode);
 int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax);
 int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax);
 void pci_bus_release_busn_res(struct pci_bus *b);
#5 lore raw
Quoted 30 lines

-----Original Message-----
From: Jiang Liu [mailto:[email protected]]
Sent: Tuesday, October 27, 2015 12:10 AM
To: Jake Oshins <[email protected]>; [email protected]; KY Srinivasan <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Haiyang Zhang <[email protected]>; [email protected]; [email protected]; [email protected]
Subject: Re: [PATCH v3 4/7] PCI: Record an fwnode associated with root PCI buses, optionally

Quoted 3 lines · On 2015/10/27 7:15, [email protected] wrote:

From: Jake Oshins <[email protected]>

This patch allows a PCI front-end implementation to supply an

fwnode_handle

Quoted 4 lines

associated with a root PCI bus, optionally. If supplied, the PCI driver records this.

This patch supports the next patch in the series, which looks up an IRQ

domain

Quoted 1 line

through this handle.

Hi JaKeo,
Instead of changing the pci_create_root_bus() interface,
how about packing fwnode into sysdata, then we may either 1) introduce a helper to retrieve fwnode from sysdata or 2) set host_bridge->fwnode = sysdata in function pcibios_root_bridge_prepare.

Quoted 3 lines

Thanks,
Gerry

Thanks for the review. I'll work up a version that uses this suggestion and resend. (I'll respond to your feedback on the other patches, too.)

-- Jake Oshins

#6 lore raw

PATCH v3 5/7 PCI: irqdomain: Look up IRQ domain by fwnode_handle

In reply to a message not in the archive

From: Jake Oshins <[email protected]>

The existing PCI code looks for an IRQ domain associated with a root PCI bus by looking in the Open Firmware tree. This patch introduces a second way to identify the associated IRQ domain, if the lookup in the OF tree fails. The handle used for the IRQ domain lookup was introduced in the previous patch in the series.

---
 drivers/pci/probe.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)
drivers/pci/probe.c +13 -0
index c0f2e44..62c9ac7 100644
@@ -664,6 +664,7 @@ 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;
+	struct pci_host_bridge *host_bridge;
 
 	/*
 	 * Any firmware interface that can resolve the msi_domain
@@ -671,6 +672,18 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
 	 */
 	d = pci_host_bridge_of_msi_domain(bus);
 
+	/*
+	 * If no IRQ domain was found via the OF tree, try looking it up
+	 * directly through the fwnode_handle.
+	 */
+	if (!d) {
+		host_bridge = to_pci_host_bridge(bus->bridge);
+		if (host_bridge->fwnode) {
+			d = irq_find_matching_fwnode(host_bridge->fwnode,
+						     DOMAIN_BUS_ANY);
+		}
+	}
+
 	return d;
 }
 
Signature · 1 line
1.9.1
#7 lore raw

Re: [PATCH v3 5/7] PCI: irqdomain: Look up IRQ domain by fwnode_handle

reproduce:

Hi Jake,

[auto build test ERROR on next-20151022 -- if it's inappropriate base, please suggest rules for selecting the more suitable base]

url:    https://github.com/0day-ci/linux/commits/jakeo-microsoft-com/New-paravirtual-PCI-front-end-for-Hyper-V-VMs/20151027-072118
config: x86_64-randconfig-x008-10252017 (attached as .config)
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

drivers/pci/probe.c: In function 'pci_host_bridge_msi_domain':

>> drivers/pci/probe.c:682:8: error: implicit declaration of function 'irq_find_matching_fwnode' [-Werror=implicit-function-declaration]
       d = irq_find_matching_fwnode(host_bridge->fwnode,
           ^
>> drivers/pci/probe.c:683:12: error: 'DOMAIN_BUS_ANY' undeclared (first use in this function)
               DOMAIN_BUS_ANY);
               ^

drivers/pci/probe.c:683:12: note: each undeclared identifier is reported only once for each function it appears in
cc1: some warnings being treated as errors

vim +/irq_find_matching_fwnode +682 drivers/pci/probe.c

676 * If no IRQ domain was found via the OF tree, try looking it up
677 * directly through the fwnode_handle.
678 */
679 if (!d) {
680 host_bridge = to_pci_host_bridge(bus->bridge);
681 if (host_bridge->fwnode) {

 > 682				d = irq_find_matching_fwnode(host_bridge->fwnode,
 > 683							     DOMAIN_BUS_ANY);

684 }
685 }
686

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation

#8 lore raw

Re: [PATCH v3 5/7] PCI: irqdomain: Look up IRQ domain by fwnode_handle

In reply to [email protected]
Quoted 28 lines · On 2015/10/27 7:15, [email protected] wrote:

From: Jake Oshins <[email protected]>

The existing PCI code looks for an IRQ domain associated with a root PCI bus by looking in the Open Firmware tree. This patch introduces a second way to identify the associated IRQ domain, if the lookup in the OF tree fails. The handle used for the IRQ domain lookup was introduced in the previous patch in the series.

---
 drivers/pci/probe.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)
drivers/pci/probe.c +1 -0
index c0f2e44..62c9ac7 100644
@@ -664,6 +664,7 @@ 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;
+	struct pci_host_bridge *host_bridge;
 
 	/*
 	 * Any firmware interface that can resolve the msi_domain
@@ -671,6 +672,18 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
 	 */
 	d = pci_host_bridge_of_msi_domain(bus);

drivers/pci/probe.c static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus) · line 683

Quoted 10 lines
drivers/pci/probe.c +9 -0
 
+	/*
+	 * If no IRQ domain was found via the OF tree, try looking it up
+	 * directly through the fwnode_handle.
+	 */
+	if (!d) {
+		host_bridge = to_pci_host_bridge(bus->bridge);
+		if (host_bridge->fwnode) {
+			d = irq_find_matching_fwnode(host_bridge->fwnode,
+						     DOMAIN_BUS_ANY);

Should we use DOMAIN_BUS_PCI_MSI instead here?

Quoted 7 lines
drivers/pci/probe.c +3 -0
+		}
+	}
+
 	return d;
 }
 
#9 lore raw

PATCH v3 6/7 drivers:hv: Define the channel type for Hyper-V PCI Express pass-through

In reply to a message not in the archive

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 ea0a0e3..5587899 100644
@@ -1140,6 +1140,17 @@ u64 hv_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

A message that is not in the archive (sent off-list or not yet received): [email protected]

#11 lore raw

Re: [PATCH v3 7/7] PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

reproduce:

Hi Jake,

[auto build test WARNING on next-20151022 -- if it's inappropriate base, please suggest rules for selecting the more suitable base]

url:    https://github.com/0day-ci/linux/commits/jakeo-microsoft-com/New-paravirtual-PCI-front-end-for-Hyper-V-VMs/20151027-072118
config: i386-allmodconfig (attached as .config)
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All warnings (new ones prefixed by >>):

drivers/pci/host/hv_pcifront.c: In function 'prepopulate_bars':

>> drivers/pci/host/hv_pcifront.c:1114:23: warning: right shift count >= width of type [-Wshift-count-overflow]
          (u32)(high_base >> 32));
                          ^
   drivers/pci/host/hv_pcifront.c: In function 'hv_pci_onchannelcallback':
>> drivers/pci/host/hv_pcifront.c:1648:18: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
       comp_packet = (struct pci_packet *)req_id;
                     ^
   drivers/pci/host/hv_pcifront.c: In function 'hv_pci_allocate_bridge_windows':
>> drivers/pci/host/hv_pcifront.c:1817:8: warning: large integer implicitly truncated to unsigned type [-Woverflow]
           0x100000000, -1,
           ^

coccinelle warnings: (new ones prefixed by >>)

>> drivers/pci/host/hv_pcifront.c:1405:31-33: ERROR: reference preceded by free on line 1383

vim +1114 drivers/pci/host/hv_pcifront.c

1098 } else {
1099 bar_val |= 0xffffffffULL << 32;
1100 }
1101 bar_size = get_bar_size(bar_val);
1102 if (high) {
1103 if (high_size != bar_size) {
1104 i++;
1105 continue;
1106 }
1107 _hv_pcifront_write_config(hpdev,
1108 PCI_BASE_ADDRESS_0 + (4 * i),
1109 4,
1110 (u32)(high_base & 0xffffff00));
1111 _hv_pcifront_write_config(hpdev,
1112 PCI_BASE_ADDRESS_0 +
1113 (4 * (i + 1)), 4,

> 1114							(u32)(high_base >> 32));

1115 high_base += bar_size;
1116 } else {
1117 if (low_size != bar_size)
1118 continue;
1119 _hv_pcifront_write_config(hpdev,
1120 PCI_BASE_ADDRESS_0 + (4 * i),
1121 4,
1122 (u32)(low_base & 0xffffff00));

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation

#12 lore raw

Re: [PATCH v3 7/7] PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

In reply to a message not in the archive
Quoted 9 lines · On 2015/10/27 7:15, [email protected] wrote:

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.

---

<snit>

Quoted 5 lines
(quoted diff) +5 -0
+
+/**
+ * hv_pcie_init_irq_domain() - Initialize IRQ domain
+ * @hbus:	The root PCI bus
+ *

Review

Quoted 10 lines
(quoted diff) +10 -0
+ * Return: '0' on success and error value on failure
+ */
+static int hv_pcie_init_irq_domain(struct hv_pcibus_device *hbus)
+{
+	hbus->msi_info.chip = &hv_msi_irq_chip;
+	hbus->msi_info.chip_data = hbus;
+	hbus->msi_info.ops = &hv_msi_ops;
+	hbus->msi_info.flags = (MSI_FLAG_USE_DEF_DOM_OPS |
+		MSI_FLAG_USE_DEF_CHIP_OPS | MSI_FLAG_MULTI_PCI_MSI |
+		MSI_FLAG_PCI_MSIX);

When interrupt remapping is not supported, x86 vector allocator can't support multiple MSI because it can't allocate continuous vectors yet. So please confirm whether we could enable MSI_FLAG_MULTI_PCI_MSI for HV.

Review

Quoted 3 lines
(quoted diff) +3 -0
+	hbus->msi_info.handler = handle_edge_irq;
+	hbus->msi_info.handler_name = "edge";
+	hbus->msi_info.data = hbus;

How about using following pattern so we could avoid exporting too many interfaces?

struct irq_domain *parent_domain = NULL; hbus->msi_info.chip = &hv_msi_irq_chip;
hbus->msi_info.ops = &hv_msi_ops;
// Let arch code to fill in default ops for chip and domain x86_setup_default_msi_irqdomian_info(&hbus->msi_info, &parent_domain); // Override default ops if not applicable
hbus->irq_domain = pci_msi_create_irq_domain(hbus->fwnode,

					     &hbus->msi_info,
					     parent_domain);
Quoted 10 lines
(quoted diff) +10 -0
+	hbus->irq_domain = pci_msi_create_irq_domain(hbus->fwnode,
+						     &hbus->msi_info,
+						     x86_vector_domain);
+	if (!hbus->irq_domain) {
+		pr_err("Failed to build an MSI IRQ domain\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
#13 lore raw

RE: [PATCH v3 7/7] PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

Quoted 15 lines

-----Original Message-----
From: Jiang Liu [mailto:[email protected]]
Sent: Tuesday, October 27, 2015 12:11 AM
To: Jake Oshins <[email protected]>; [email protected]; KY Srinivasan <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Haiyang Zhang <[email protected]>; [email protected]; [email protected]; [email protected]
Subject: Re: [PATCH v3 7/7] PCI: hv: New paravirtual PCI front-end for Hyper- V VMs

Quoted 2 lines · On 2015/10/27 7:15, [email protected] wrote:

From: Jake Oshins <[email protected]>

(snip)

Quoted 14 lines

Review

Quoted 13 lines
(quoted diff) +13 -0
+/**
+ * hv_pcie_init_irq_domain() - Initialize IRQ domain
+ * @hbus:	The root PCI bus
+ *
+ * Return: '0' on success and error value on failure
+ */
+static int hv_pcie_init_irq_domain(struct hv_pcibus_device *hbus)
+{
+	hbus->msi_info.chip = &hv_msi_irq_chip;
+	hbus->msi_info.chip_data = hbus;
+	hbus->msi_info.ops = &hv_msi_ops;
+	hbus->msi_info.flags = (MSI_FLAG_USE_DEF_DOM_OPS |
+		MSI_FLAG_USE_DEF_CHIP_OPS |

MSI_FLAG_MULTI_PCI_MSI |

Quoted 6 lines

Review

Quoted 1 line
(quoted diff) +1 -0
+		MSI_FLAG_PCI_MSIX);

When interrupt remapping is not supported, x86 vector allocator can't support multiple MSI because it can't allocate continuous vectors yet. So please confirm whether we could enable MSI_FLAG_MULTI_PCI_MSI for HV.

We can actually handle the remapping in the hypervisor. I'll add a comment to that effect.

Quoted 14 lines

Review

Quoted 3 lines
(quoted diff) +3 -0
+	hbus->msi_info.handler = handle_edge_irq;
+	hbus->msi_info.handler_name = "edge";
+	hbus->msi_info.data = hbus;

How about using following pattern so we could avoid exporting too many interfaces?

struct irq_domain *parent_domain = NULL; hbus->msi_info.chip = &hv_msi_irq_chip; hbus->msi_info.ops = &hv_msi_ops;
// Let arch code to fill in default ops for chip and domain x86_setup_default_msi_irqdomian_info(&hbus->msi_info, &parent_domain);
// Override default ops if not applicable hbus->irq_domain = pci_msi_create_irq_domain(hbus->fwnode,

Quoted 3 lines
					     &hbus->msi_info,
					     parent_domain);

I understand your point here, but I'm having trouble making it play out. When I look at this, the only functions or structures which are supplied straight from exports (in my proposed patches) are irq_chip_ack_parent(), pci_msi_prepare() and x86_vector_domain. The other exports either already exist for other reasons or they're needed within functions that I need to supply. If you feel strongly that adding a new function to avoid exporting these is the right way to go, I'll do it, but I want to confirm that first.

Thanks,
Jake Oshins

#14 lore raw

Re: [PATCH v3 7/7] PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

Quoted 57 lines · Jake Oshins
Quoted 15 lines

-----Original Message-----
From: Jiang Liu [mailto:[email protected]]
Sent: Tuesday, October 27, 2015 12:11 AM
To: Jake Oshins <[email protected]>; [email protected]; KY Srinivasan <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Haiyang Zhang <[email protected]>; [email protected]; [email protected]; [email protected]
Subject: Re: [PATCH v3 7/7] PCI: hv: New paravirtual PCI front-end for Hyper- V VMs

Quoted 2 lines · On 2015/10/27 7:15, [email protected] wrote:

From: Jake Oshins <[email protected]>

(snip)

Quoted 14 lines

Review

Quoted 13 lines
(quoted diff) +13 -0
+/**
+ * hv_pcie_init_irq_domain() - Initialize IRQ domain
+ * @hbus:	The root PCI bus
+ *
+ * Return: '0' on success and error value on failure
+ */
+static int hv_pcie_init_irq_domain(struct hv_pcibus_device *hbus)
+{
+	hbus->msi_info.chip = &hv_msi_irq_chip;
+	hbus->msi_info.chip_data = hbus;
+	hbus->msi_info.ops = &hv_msi_ops;
+	hbus->msi_info.flags = (MSI_FLAG_USE_DEF_DOM_OPS |
+		MSI_FLAG_USE_DEF_CHIP_OPS |

MSI_FLAG_MULTI_PCI_MSI |

Quoted 6 lines

Review

Quoted 1 line
(quoted diff) +1 -0
+		MSI_FLAG_PCI_MSIX);

When interrupt remapping is not supported, x86 vector allocator can't support multiple MSI because it can't allocate continuous vectors yet. So please confirm whether we could enable MSI_FLAG_MULTI_PCI_MSI for HV.

We can actually handle the remapping in the hypervisor. I'll add a comment to that effect.

Quoted 14 lines

Review

Quoted 3 lines
(quoted diff) +3 -0
+	hbus->msi_info.handler = handle_edge_irq;
+	hbus->msi_info.handler_name = "edge";
+	hbus->msi_info.data = hbus;

How about using following pattern so we could avoid exporting too many interfaces?

struct irq_domain *parent_domain = NULL; hbus->msi_info.chip = &hv_msi_irq_chip; hbus->msi_info.ops = &hv_msi_ops;
// Let arch code to fill in default ops for chip and domain x86_setup_default_msi_irqdomian_info(&hbus->msi_info, &parent_domain);
// Override default ops if not applicable hbus->irq_domain = pci_msi_create_irq_domain(hbus->fwnode,

Quoted 3 lines
					     &hbus->msi_info,
					     parent_domain);
Quoted 1 line

I understand your point here, but I'm having trouble making it play out. When I look at this, the only functions or structures which are supplied straight from exports (in my proposed patches) are irq_chip_ack_parent(), pci_msi_prepare() and x86_vector_domain. The other exports either already exist for other reasons or they're needed within functions that I need to supply. If you feel strongly that adding a new function to avoid exporting these is the right way to go, I'll do it, but I want to confirm that first.

No strong preference here, just feeling that pci_msi_prepare() and x86_vector_domain are arch specific:)

And I was hoping that we could find some commonality between this driver and the VMD driver posted at http://lkml.org/lkml/2015/10/27/607
so we could abstract the common part into core.

For the VMD driver, it has put the code to create irqdomain into core as vmd_create_irq_domain().

Thanks,
Gerry

Quoted 4 lines

Thanks,
Jake Oshins