All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/13] PCI: sparc related 64bit resource fixup
@ 2017-04-21  5:04 Yinghai Lu
  2017-04-21  5:04   ` Yinghai Lu
                   ` (12 more replies)
  0 siblings, 13 replies; 33+ messages in thread
From: Yinghai Lu @ 2017-04-21  5:04 UTC (permalink / raw)
  To: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt
  Cc: Wei Yang, Khalid Aziz, linux-pci, linux-kernel, Yinghai Lu

Hi Bjorn,

Please check sparc related 64bit resource handling patches.

patch 1-8: parse MEM64 for sparc and other system with OF.
	So device 64bit resource could find their parent resource.

patch 9-12: MMIO64 handling enhancement
        treat non-pref mmio64 as pref mmio64 if all bridges to root all pcie.

patch 13: restore old pref allocation logic if hostbridge does not support mmio64.

Those patches could be applied on top of today's pci/next.

Thanks

Yinghai


Yinghai Lu (13):
  sparc/PCI: Use correct offset for bus address to resource
  PCI: Add pci_find_bus_resource()
  sparc/PCI: Reserve legacy mmio after PCI mmio
  sparc/PCI: Add IORESOURCE_MEM_64 for 64-bit resource in OF parsing
  sparc/PCI: Keep resource idx order with bridge register number
  powerpc/PCI: Keep resource idx order with bridge register number
  powerpc/PCI: Add IORESOURCE_MEM_64 for 64-bit resource in OF parsing
  OF/PCI: Add IORESOURCE_MEM_64 for 64-bit resource
  PCI: Check pref compatible bit for mem64 resource of PCIe device
  PCI: Only treat non-pref mmio64 as pref if all bridges have MEM_64
  PCI: Add has_mem64 for struct host_bridge
  PCI: Only treat non-pref mmio64 as pref if host bridge has mmio64
  PCI: Restore pref MMIO allocation logic for host bridge without mmio64

 arch/powerpc/kernel/pci_of_scan.c | 12 +++++-
 arch/sparc/kernel/of_device_32.c  |  5 ++-
 arch/sparc/kernel/of_device_64.c  |  5 ++-
 arch/sparc/kernel/pci.c           | 15 +++++--
 arch/sparc/kernel/pci_common.c    | 91 +++++++++++++++++++++++----------------
 arch/sparc/kernel/pci_impl.h      |  5 +++
 drivers/of/address.c              |  4 +-
 drivers/pci/bus.c                 |  4 +-
 drivers/pci/pci.c                 | 31 +++++++------
 drivers/pci/pci.h                 |  2 +
 drivers/pci/probe.c               | 40 +++++++++++++++++
 drivers/pci/setup-bus.c           | 65 ++++++++++++++++++++++++----
 drivers/pci/setup-res.c           | 13 ++++--
 include/linux/pci.h               |  4 ++
 14 files changed, 224 insertions(+), 72 deletions(-)

-- 
2.9.3

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

* [PATCH 01/13] sparc/PCI: Use correct offset for bus address to resource
  2017-04-21  5:04 [PATCH 00/13] PCI: sparc related 64bit resource fixup Yinghai Lu
@ 2017-04-21  5:04   ` Yinghai Lu
  2017-04-21  5:04 ` [PATCH 02/13] PCI: Add pci_find_bus_resource() Yinghai Lu
                     ` (11 subsequent siblings)
  12 siblings, 0 replies; 33+ messages in thread
From: Yinghai Lu @ 2017-04-21  5:04 UTC (permalink / raw)
  To: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt
  Cc: Wei Yang, Khalid Aziz, linux-pci, linux-kernel, Yinghai Lu, sparclinux

After we added 64bit mmio parsing, we got some "no compatible bridge window"
warning on anther new model that support 64bit resource.

It turns out that we can not use mem_space.start as 64bit mem space
offset, aka there is mem_space.start != offset.

Use child_phys_addr to calculate exact offset and record offset in
pbm.

After patch we get correct offset.

/pci@305: PCI IO [io  0x2007e00000000-0x2007e0fffffff] offset 2007e00000000
/pci@305: PCI MEM [mem 0x2000000100000-0x200007effffff] offset 2000000000000
/pci@305: PCI MEM64 [mem 0x2000100000000-0x2000dffffffff] offset 2000000000000
...
pci_sun4v f02ae7f8: PCI host bridge to bus 0000:00
pci_bus 0000:00: root bus resource [io  0x2007e00000000-0x2007e0fffffff] (bus address [0x0000-0xfffffff])
pci_bus 0000:00: root bus resource [mem 0x2000000100000-0x200007effffff] (bus address [0x00100000-0x7effffff])
pci_bus 0000:00: root bus resource [mem 0x2000100000000-0x2000dffffffff] (bus address [0x100000000-0xdffffffff])

-v3: put back mem64_offset, as we found T4 has mem_offset != mem64_offset
     check overlapping between mem64_space and mem_space.
-v7: after new pci_mmap_page_range patches.
-v8: remove change in pci_resource_to_user()

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
Cc: sparclinux@vger.kernel.org
---
 arch/sparc/kernel/pci.c        |  6 +++---
 arch/sparc/kernel/pci_common.c | 32 ++++++++++++++++++++++++--------
 arch/sparc/kernel/pci_impl.h   |  4 ++++
 3 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index 7eceaa1..c5cf813 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -663,12 +663,12 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
 	printk("PCI: Scanning PBM %s\n", node->full_name);
 
 	pci_add_resource_offset(&resources, &pbm->io_space,
-				pbm->io_space.start);
+				pbm->io_offset);
 	pci_add_resource_offset(&resources, &pbm->mem_space,
-				pbm->mem_space.start);
+				pbm->mem_offset);
 	if (pbm->mem64_space.flags)
 		pci_add_resource_offset(&resources, &pbm->mem64_space,
-					pbm->mem_space.start);
+					pbm->mem64_offset);
 	pbm->busn.start = pbm->pci_first_busno;
 	pbm->busn.end	= pbm->pci_last_busno;
 	pbm->busn.flags	= IORESOURCE_BUS;
diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c
index 33524c1..76998f8 100644
--- a/arch/sparc/kernel/pci_common.c
+++ b/arch/sparc/kernel/pci_common.c
@@ -410,13 +410,16 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
 
 	for (i = 0; i < num_pbm_ranges; i++) {
 		const struct linux_prom_pci_ranges *pr = &pbm_ranges[i];
-		unsigned long a, size;
+		unsigned long a, size, region_a;
 		u32 parent_phys_hi, parent_phys_lo;
+		u32 child_phys_mid, child_phys_lo;
 		u32 size_hi, size_lo;
 		int type;
 
 		parent_phys_hi = pr->parent_phys_hi;
 		parent_phys_lo = pr->parent_phys_lo;
+		child_phys_mid = pr->child_phys_mid;
+		child_phys_lo = pr->child_phys_lo;
 		if (tlb_type == hypervisor)
 			parent_phys_hi &= 0x0fffffff;
 
@@ -426,6 +429,8 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
 		type = (pr->child_phys_hi >> 24) & 0x3;
 		a = (((unsigned long)parent_phys_hi << 32UL) |
 		     ((unsigned long)parent_phys_lo  <<  0UL));
+		region_a = (((unsigned long)child_phys_mid << 32UL) |
+		     ((unsigned long)child_phys_lo  <<  0UL));
 		size = (((unsigned long)size_hi << 32UL) |
 			((unsigned long)size_lo  <<  0UL));
 
@@ -440,6 +445,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
 			pbm->io_space.start = a;
 			pbm->io_space.end = a + size - 1UL;
 			pbm->io_space.flags = IORESOURCE_IO;
+			pbm->io_offset = a - region_a;
 			saw_io = 1;
 			break;
 
@@ -448,6 +454,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
 			pbm->mem_space.start = a;
 			pbm->mem_space.end = a + size - 1UL;
 			pbm->mem_space.flags = IORESOURCE_MEM;
+			pbm->mem_offset = a - region_a;
 			saw_mem = 1;
 			break;
 
@@ -456,6 +463,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
 			pbm->mem64_space.start = a;
 			pbm->mem64_space.end = a + size - 1UL;
 			pbm->mem64_space.flags = IORESOURCE_MEM;
+			pbm->mem64_offset = a - region_a;
 			saw_mem = 1;
 			break;
 
@@ -471,14 +479,22 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
 		prom_halt();
 	}
 
-	printk("%s: PCI IO[%llx] MEM[%llx]",
-	       pbm->name,
-	       pbm->io_space.start,
-	       pbm->mem_space.start);
+	if (pbm->io_space.flags)
+		printk("%s: PCI IO %pR offset %llx\n",
+		       pbm->name, &pbm->io_space, pbm->io_offset);
+	if (pbm->mem_space.flags)
+		printk("%s: PCI MEM %pR offset %llx\n",
+		       pbm->name, &pbm->mem_space, pbm->mem_offset);
+	if (pbm->mem64_space.flags && pbm->mem_space.flags) {
+		if (pbm->mem64_space.start <= pbm->mem_space.end)
+			pbm->mem64_space.start = pbm->mem_space.end + 1;
+		if (pbm->mem64_space.start > pbm->mem64_space.end)
+			pbm->mem64_space.flags = 0;
+	}
+
 	if (pbm->mem64_space.flags)
-		printk(" MEM64[%llx]",
-		       pbm->mem64_space.start);
-	printk("\n");
+		printk("%s: PCI MEM64 %pR offset %llx\n",
+		       pbm->name, &pbm->mem64_space, pbm->mem64_offset);
 
 	pbm->io_space.name = pbm->mem_space.name = pbm->name;
 	pbm->mem64_space.name = pbm->name;
diff --git a/arch/sparc/kernel/pci_impl.h b/arch/sparc/kernel/pci_impl.h
index 37222ca..2853af7 100644
--- a/arch/sparc/kernel/pci_impl.h
+++ b/arch/sparc/kernel/pci_impl.h
@@ -99,6 +99,10 @@ struct pci_pbm_info {
 	struct resource			mem_space;
 	struct resource			mem64_space;
 	struct resource			busn;
+	/* offset */
+	resource_size_t			io_offset;
+	resource_size_t			mem_offset;
+	resource_size_t			mem64_offset;
 
 	/* Base of PCI Config space, can be per-PBM or shared. */
 	unsigned long			config_space;
-- 
2.9.3

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

* [PATCH 01/13] sparc/PCI: Use correct offset for bus address to resource
@ 2017-04-21  5:04   ` Yinghai Lu
  0 siblings, 0 replies; 33+ messages in thread
From: Yinghai Lu @ 2017-04-21  5:04 UTC (permalink / raw)
  To: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt
  Cc: Wei Yang, Khalid Aziz, linux-pci, linux-kernel, Yinghai Lu, sparclinux

After we added 64bit mmio parsing, we got some "no compatible bridge window"
warning on anther new model that support 64bit resource.

It turns out that we can not use mem_space.start as 64bit mem space
offset, aka there is mem_space.start != offset.

Use child_phys_addr to calculate exact offset and record offset in
pbm.

After patch we get correct offset.

/pci@305: PCI IO [io  0x2007e00000000-0x2007e0fffffff] offset 2007e00000000
/pci@305: PCI MEM [mem 0x2000000100000-0x200007effffff] offset 2000000000000
/pci@305: PCI MEM64 [mem 0x2000100000000-0x2000dffffffff] offset 2000000000000
...
pci_sun4v f02ae7f8: PCI host bridge to bus 0000:00
pci_bus 0000:00: root bus resource [io  0x2007e00000000-0x2007e0fffffff] (bus address [0x0000-0xfffffff])
pci_bus 0000:00: root bus resource [mem 0x2000000100000-0x200007effffff] (bus address [0x00100000-0x7effffff])
pci_bus 0000:00: root bus resource [mem 0x2000100000000-0x2000dffffffff] (bus address [0x100000000-0xdffffffff])

-v3: put back mem64_offset, as we found T4 has mem_offset != mem64_offset
     check overlapping between mem64_space and mem_space.
-v7: after new pci_mmap_page_range patches.
-v8: remove change in pci_resource_to_user()

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
Cc: sparclinux@vger.kernel.org
---
 arch/sparc/kernel/pci.c        |  6 +++---
 arch/sparc/kernel/pci_common.c | 32 ++++++++++++++++++++++++--------
 arch/sparc/kernel/pci_impl.h   |  4 ++++
 3 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index 7eceaa1..c5cf813 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -663,12 +663,12 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
 	printk("PCI: Scanning PBM %s\n", node->full_name);
 
 	pci_add_resource_offset(&resources, &pbm->io_space,
-				pbm->io_space.start);
+				pbm->io_offset);
 	pci_add_resource_offset(&resources, &pbm->mem_space,
-				pbm->mem_space.start);
+				pbm->mem_offset);
 	if (pbm->mem64_space.flags)
 		pci_add_resource_offset(&resources, &pbm->mem64_space,
-					pbm->mem_space.start);
+					pbm->mem64_offset);
 	pbm->busn.start = pbm->pci_first_busno;
 	pbm->busn.end	= pbm->pci_last_busno;
 	pbm->busn.flags	= IORESOURCE_BUS;
diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c
index 33524c1..76998f8 100644
--- a/arch/sparc/kernel/pci_common.c
+++ b/arch/sparc/kernel/pci_common.c
@@ -410,13 +410,16 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
 
 	for (i = 0; i < num_pbm_ranges; i++) {
 		const struct linux_prom_pci_ranges *pr = &pbm_ranges[i];
-		unsigned long a, size;
+		unsigned long a, size, region_a;
 		u32 parent_phys_hi, parent_phys_lo;
+		u32 child_phys_mid, child_phys_lo;
 		u32 size_hi, size_lo;
 		int type;
 
 		parent_phys_hi = pr->parent_phys_hi;
 		parent_phys_lo = pr->parent_phys_lo;
+		child_phys_mid = pr->child_phys_mid;
+		child_phys_lo = pr->child_phys_lo;
 		if (tlb_type = hypervisor)
 			parent_phys_hi &= 0x0fffffff;
 
@@ -426,6 +429,8 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
 		type = (pr->child_phys_hi >> 24) & 0x3;
 		a = (((unsigned long)parent_phys_hi << 32UL) |
 		     ((unsigned long)parent_phys_lo  <<  0UL));
+		region_a = (((unsigned long)child_phys_mid << 32UL) |
+		     ((unsigned long)child_phys_lo  <<  0UL));
 		size = (((unsigned long)size_hi << 32UL) |
 			((unsigned long)size_lo  <<  0UL));
 
@@ -440,6 +445,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
 			pbm->io_space.start = a;
 			pbm->io_space.end = a + size - 1UL;
 			pbm->io_space.flags = IORESOURCE_IO;
+			pbm->io_offset = a - region_a;
 			saw_io = 1;
 			break;
 
@@ -448,6 +454,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
 			pbm->mem_space.start = a;
 			pbm->mem_space.end = a + size - 1UL;
 			pbm->mem_space.flags = IORESOURCE_MEM;
+			pbm->mem_offset = a - region_a;
 			saw_mem = 1;
 			break;
 
@@ -456,6 +463,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
 			pbm->mem64_space.start = a;
 			pbm->mem64_space.end = a + size - 1UL;
 			pbm->mem64_space.flags = IORESOURCE_MEM;
+			pbm->mem64_offset = a - region_a;
 			saw_mem = 1;
 			break;
 
@@ -471,14 +479,22 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
 		prom_halt();
 	}
 
-	printk("%s: PCI IO[%llx] MEM[%llx]",
-	       pbm->name,
-	       pbm->io_space.start,
-	       pbm->mem_space.start);
+	if (pbm->io_space.flags)
+		printk("%s: PCI IO %pR offset %llx\n",
+		       pbm->name, &pbm->io_space, pbm->io_offset);
+	if (pbm->mem_space.flags)
+		printk("%s: PCI MEM %pR offset %llx\n",
+		       pbm->name, &pbm->mem_space, pbm->mem_offset);
+	if (pbm->mem64_space.flags && pbm->mem_space.flags) {
+		if (pbm->mem64_space.start <= pbm->mem_space.end)
+			pbm->mem64_space.start = pbm->mem_space.end + 1;
+		if (pbm->mem64_space.start > pbm->mem64_space.end)
+			pbm->mem64_space.flags = 0;
+	}
+
 	if (pbm->mem64_space.flags)
-		printk(" MEM64[%llx]",
-		       pbm->mem64_space.start);
-	printk("\n");
+		printk("%s: PCI MEM64 %pR offset %llx\n",
+		       pbm->name, &pbm->mem64_space, pbm->mem64_offset);
 
 	pbm->io_space.name = pbm->mem_space.name = pbm->name;
 	pbm->mem64_space.name = pbm->name;
diff --git a/arch/sparc/kernel/pci_impl.h b/arch/sparc/kernel/pci_impl.h
index 37222ca..2853af7 100644
--- a/arch/sparc/kernel/pci_impl.h
+++ b/arch/sparc/kernel/pci_impl.h
@@ -99,6 +99,10 @@ struct pci_pbm_info {
 	struct resource			mem_space;
 	struct resource			mem64_space;
 	struct resource			busn;
+	/* offset */
+	resource_size_t			io_offset;
+	resource_size_t			mem_offset;
+	resource_size_t			mem64_offset;
 
 	/* Base of PCI Config space, can be per-PBM or shared. */
 	unsigned long			config_space;
-- 
2.9.3


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

* [PATCH 02/13] PCI: Add pci_find_bus_resource()
  2017-04-21  5:04 [PATCH 00/13] PCI: sparc related 64bit resource fixup Yinghai Lu
  2017-04-21  5:04   ` Yinghai Lu
@ 2017-04-21  5:04 ` Yinghai Lu
  2017-04-21  5:04   ` Yinghai Lu
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 33+ messages in thread
From: Yinghai Lu @ 2017-04-21  5:04 UTC (permalink / raw)
  To: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt
  Cc: Wei Yang, Khalid Aziz, linux-pci, linux-kernel, Yinghai Lu

Add pci_find_bus_resource() to return bus resource for input resource.

In some case, we may only have bus instead of dev.
It is same as pci_find_parent_resource, but take bus as input.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/pci.c   | 27 ++++++++++++++++-----------
 include/linux/pci.h |  2 ++
 2 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 4ffa152..deb828f 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -437,18 +437,9 @@ int pci_find_ht_capability(struct pci_dev *dev, int ht_cap)
 }
 EXPORT_SYMBOL_GPL(pci_find_ht_capability);
 
-/**
- * pci_find_parent_resource - return resource region of parent bus of given region
- * @dev: PCI device structure contains resources to be searched
- * @res: child resource record for which parent is sought
- *
- *  For given resource region of given device, return the resource
- *  region of parent bus the given region is contained in.
- */
-struct resource *pci_find_parent_resource(const struct pci_dev *dev,
-					  struct resource *res)
+struct resource *pci_find_bus_resource(const struct pci_bus *bus,
+					struct resource *res)
 {
-	const struct pci_bus *bus = dev->bus;
 	struct resource *r;
 	int i;
 
@@ -478,6 +469,20 @@ struct resource *pci_find_parent_resource(const struct pci_dev *dev,
 	}
 	return NULL;
 }
+
+/**
+ * pci_find_parent_resource - return resource region of parent bus of given region
+ * @dev: PCI device structure contains resources to be searched
+ * @res: child resource record for which parent is sought
+ *
+ *  For given resource region of given device, return the resource
+ *  region of parent bus the given region is contained in.
+ */
+struct resource *pci_find_parent_resource(const struct pci_dev *dev,
+					  struct resource *res)
+{
+	return pci_find_bus_resource(dev->bus, res);
+}
 EXPORT_SYMBOL(pci_find_parent_resource);
 
 /**
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 88185ff..817786b 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -836,6 +836,8 @@ void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,
 			     struct resource *res);
 void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res,
 			     struct pci_bus_region *region);
+struct resource *pci_find_bus_resource(const struct pci_bus *bus,
+					struct resource *res);
 void pcibios_scan_specific_bus(int busn);
 struct pci_bus *pci_find_bus(int domain, int busnr);
 void pci_bus_add_devices(const struct pci_bus *bus);
-- 
2.9.3

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

* [PATCH 03/13] sparc/PCI: Reserve legacy mmio after PCI mmio
  2017-04-21  5:04 [PATCH 00/13] PCI: sparc related 64bit resource fixup Yinghai Lu
@ 2017-04-21  5:04   ` Yinghai Lu
  2017-04-21  5:04 ` [PATCH 02/13] PCI: Add pci_find_bus_resource() Yinghai Lu
                     ` (11 subsequent siblings)
  12 siblings, 0 replies; 33+ messages in thread
From: Yinghai Lu @ 2017-04-21  5:04 UTC (permalink / raw)
  To: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt
  Cc: Wei Yang, Khalid Aziz, linux-pci, linux-kernel, Yinghai Lu, sparclinux

On one system found bunch of claim resource fail from pci device.
pci_sun4v f02b894c: PCI host bridge to bus 0000:00
pci_bus 0000:00: root bus resource [io  0x2007e00000000-0x2007e0fffffff] (bus address [0x0000-0xfffffff])
pci_bus 0000:00: root bus resource [mem 0x2000000000000-0x200007effffff] (bus address [0x00000000-0x7effffff])
pci_bus 0000:00: root bus resource [mem 0x2000100000000-0x20007ffffffff] (bus address [0x100000000-0x7ffffffff])
...
PCI: Claiming 0000:00:02.0: Resource 14: 0002000000000000..00020000004fffff [200]
pci 0000:00:02.0: can't claim BAR 14 [mem 0x2000000000000-0x20000004fffff]: address conflict with Video RAM area [??? 0x20000000a0000-0x20000000bffff flags 0x80000000]
pci 0000:02:00.0: can't claim BAR 0 [mem 0x2000000000000-0x20000000fffff]: no compatible bridge window
PCI: Claiming 0000:02:00.0: Resource 3: 0002000000100000..0002000000103fff [200]
pci 0000:02:00.0: can't claim BAR 3 [mem 0x2000000100000-0x2000000103fff]: no compatible bridge window
PCI: Claiming 0000:02:00.1: Resource 0: 0002000000200000..00020000002fffff [200]
pci 0000:02:00.1: can't claim BAR 0 [mem 0x2000000200000-0x20000002fffff]: no compatible bridge window
PCI: Claiming 0000:02:00.1: Resource 3: 0002000000104000..0002000000107fff [200]
pci 0000:02:00.1: can't claim BAR 3 [mem 0x2000000104000-0x2000000107fff]: no compatible bridge window
PCI: Claiming 0000:02:00.2: Resource 0: 0002000000300000..00020000003fffff [200]
pci 0000:02:00.2: can't claim BAR 0 [mem 0x2000000300000-0x20000003fffff]: no compatible bridge window
PCI: Claiming 0000:02:00.2: Resource 3: 0002000000108000..000200000010bfff [200]
pci 0000:02:00.2: can't claim BAR 3 [mem 0x2000000108000-0x200000010bfff]: no compatible bridge window
PCI: Claiming 0000:02:00.3: Resource 0: 0002000000400000..00020000004fffff [200]
pci 0000:02:00.3: can't claim BAR 0 [mem 0x2000000400000-0x20000004fffff]: no compatible bridge window
PCI: Claiming 0000:02:00.3: Resource 3: 000200000010c000..000200000010ffff [200]
pci 0000:02:00.3: can't claim BAR 3 [mem 0x200000010c000-0x200000010ffff]: no compatible bridge window

The bridge 00:02.0 resource does not get reserved as Video RAM take the position early,
and following children resources reservation all fail.

Move down Video RAM area reservation after pci mmio get reserved,
so we leave pci driver to use those regions.

-v5: merge simplify one and use pcibios_bus_to_resource()

-v6: use pci_find_bus_resource()

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
Cc: sparclinux@vger.kernel.org
---
 arch/sparc/kernel/pci.c        |  1 +
 arch/sparc/kernel/pci_common.c | 59 ++++++++++++++++++++++--------------------
 arch/sparc/kernel/pci_impl.h   |  1 +
 3 files changed, 33 insertions(+), 28 deletions(-)

diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index c5cf813..adb9653 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -686,6 +686,7 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
 	pci_bus_register_of_sysfs(bus);
 
 	pci_claim_bus_resources(bus);
+	pci_register_legacy_regions(bus);
 	pci_bus_add_devices(bus);
 	return bus;
 }
diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c
index 76998f8..1ebc7ff 100644
--- a/arch/sparc/kernel/pci_common.c
+++ b/arch/sparc/kernel/pci_common.c
@@ -328,41 +328,46 @@ void pci_get_pbm_props(struct pci_pbm_info *pbm)
 	}
 }
 
-static void pci_register_legacy_regions(struct resource *io_res,
-					struct resource *mem_res)
+static void pci_register_region(struct pci_bus *bus, const char *name,
+				resource_size_t rstart, resource_size_t size)
 {
-	struct resource *p;
+	struct resource *res, *conflict, *bus_res;
+	struct pci_bus_region region;
 
-	/* VGA Video RAM. */
-	p = kzalloc(sizeof(*p), GFP_KERNEL);
-	if (!p)
+	res = kzalloc(sizeof(*res), GFP_KERNEL);
+	if (!res)
 		return;
 
-	p->name = "Video RAM area";
-	p->start = mem_res->start + 0xa0000UL;
-	p->end = p->start + 0x1ffffUL;
-	p->flags = IORESOURCE_BUSY;
-	request_resource(mem_res, p);
+	res->flags = IORESOURCE_MEM;
 
-	p = kzalloc(sizeof(*p), GFP_KERNEL);
-	if (!p)
+	region.start = rstart;
+	region.end = rstart + size - 1UL;
+	pcibios_bus_to_resource(bus, res, &region);
+	bus_res = pci_find_bus_resource(bus, res);
+	if (!bus_res) {
+		kfree(res);
 		return;
+	}
+
+	res->name = name;
+	res->flags |= IORESOURCE_BUSY;
+	conflict = request_resource_conflict(bus_res, res);
+	if (conflict) {
+		dev_printk(KERN_DEBUG, &bus->dev,
+			" can't claim %s %pR: address conflict with %s %pR\n",
+			res->name, res, conflict->name, conflict);
+		kfree(res);
+	}
+}
 
-	p->name = "System ROM";
-	p->start = mem_res->start + 0xf0000UL;
-	p->end = p->start + 0xffffUL;
-	p->flags = IORESOURCE_BUSY;
-	request_resource(mem_res, p);
+void pci_register_legacy_regions(struct pci_bus *bus)
+{
+	/* VGA Video RAM. */
+	pci_register_region(bus, "Video RAM area", 0xa0000UL, 0x20000UL);
 
-	p = kzalloc(sizeof(*p), GFP_KERNEL);
-	if (!p)
-		return;
+	pci_register_region(bus, "System ROM",     0xf0000UL, 0x10000UL);
 
-	p->name = "Video ROM";
-	p->start = mem_res->start + 0xc0000UL;
-	p->end = p->start + 0x7fffUL;
-	p->flags = IORESOURCE_BUSY;
-	request_resource(mem_res, p);
+	pci_register_region(bus, "Video ROM",      0xc0000UL,  0x8000UL);
 }
 
 static void pci_register_iommu_region(struct pci_pbm_info *pbm)
@@ -504,8 +509,6 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
 	if (pbm->mem64_space.flags)
 		request_resource(&iomem_resource, &pbm->mem64_space);
 
-	pci_register_legacy_regions(&pbm->io_space,
-				    &pbm->mem_space);
 	pci_register_iommu_region(pbm);
 }
 
diff --git a/arch/sparc/kernel/pci_impl.h b/arch/sparc/kernel/pci_impl.h
index 2853af7..ff8f5e1 100644
--- a/arch/sparc/kernel/pci_impl.h
+++ b/arch/sparc/kernel/pci_impl.h
@@ -167,6 +167,7 @@ void pci_get_pbm_props(struct pci_pbm_info *pbm);
 struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
 				 struct device *parent);
 void pci_determine_mem_io_space(struct pci_pbm_info *pbm);
+void pci_register_legacy_regions(struct pci_bus *bus);
 
 /* Error reporting support. */
 void pci_scan_for_target_abort(struct pci_pbm_info *, struct pci_bus *);
-- 
2.9.3

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

* [PATCH 03/13] sparc/PCI: Reserve legacy mmio after PCI mmio
@ 2017-04-21  5:04   ` Yinghai Lu
  0 siblings, 0 replies; 33+ messages in thread
From: Yinghai Lu @ 2017-04-21  5:04 UTC (permalink / raw)
  To: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt
  Cc: Wei Yang, Khalid Aziz, linux-pci, linux-kernel, Yinghai Lu, sparclinux

On one system found bunch of claim resource fail from pci device.
pci_sun4v f02b894c: PCI host bridge to bus 0000:00
pci_bus 0000:00: root bus resource [io  0x2007e00000000-0x2007e0fffffff] (bus address [0x0000-0xfffffff])
pci_bus 0000:00: root bus resource [mem 0x2000000000000-0x200007effffff] (bus address [0x00000000-0x7effffff])
pci_bus 0000:00: root bus resource [mem 0x2000100000000-0x20007ffffffff] (bus address [0x100000000-0x7ffffffff])
...
PCI: Claiming 0000:00:02.0: Resource 14: 0002000000000000..00020000004fffff [200]
pci 0000:00:02.0: can't claim BAR 14 [mem 0x2000000000000-0x20000004fffff]: address conflict with Video RAM area [??? 0x20000000a0000-0x20000000bffff flags 0x80000000]
pci 0000:02:00.0: can't claim BAR 0 [mem 0x2000000000000-0x20000000fffff]: no compatible bridge window
PCI: Claiming 0000:02:00.0: Resource 3: 0002000000100000..0002000000103fff [200]
pci 0000:02:00.0: can't claim BAR 3 [mem 0x2000000100000-0x2000000103fff]: no compatible bridge window
PCI: Claiming 0000:02:00.1: Resource 0: 0002000000200000..00020000002fffff [200]
pci 0000:02:00.1: can't claim BAR 0 [mem 0x2000000200000-0x20000002fffff]: no compatible bridge window
PCI: Claiming 0000:02:00.1: Resource 3: 0002000000104000..0002000000107fff [200]
pci 0000:02:00.1: can't claim BAR 3 [mem 0x2000000104000-0x2000000107fff]: no compatible bridge window
PCI: Claiming 0000:02:00.2: Resource 0: 0002000000300000..00020000003fffff [200]
pci 0000:02:00.2: can't claim BAR 0 [mem 0x2000000300000-0x20000003fffff]: no compatible bridge window
PCI: Claiming 0000:02:00.2: Resource 3: 0002000000108000..000200000010bfff [200]
pci 0000:02:00.2: can't claim BAR 3 [mem 0x2000000108000-0x200000010bfff]: no compatible bridge window
PCI: Claiming 0000:02:00.3: Resource 0: 0002000000400000..00020000004fffff [200]
pci 0000:02:00.3: can't claim BAR 0 [mem 0x2000000400000-0x20000004fffff]: no compatible bridge window
PCI: Claiming 0000:02:00.3: Resource 3: 000200000010c000..000200000010ffff [200]
pci 0000:02:00.3: can't claim BAR 3 [mem 0x200000010c000-0x200000010ffff]: no compatible bridge window

The bridge 00:02.0 resource does not get reserved as Video RAM take the position early,
and following children resources reservation all fail.

Move down Video RAM area reservation after pci mmio get reserved,
so we leave pci driver to use those regions.

-v5: merge simplify one and use pcibios_bus_to_resource()

-v6: use pci_find_bus_resource()

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
Cc: sparclinux@vger.kernel.org
---
 arch/sparc/kernel/pci.c        |  1 +
 arch/sparc/kernel/pci_common.c | 59 ++++++++++++++++++++++--------------------
 arch/sparc/kernel/pci_impl.h   |  1 +
 3 files changed, 33 insertions(+), 28 deletions(-)

diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index c5cf813..adb9653 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -686,6 +686,7 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
 	pci_bus_register_of_sysfs(bus);
 
 	pci_claim_bus_resources(bus);
+	pci_register_legacy_regions(bus);
 	pci_bus_add_devices(bus);
 	return bus;
 }
diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c
index 76998f8..1ebc7ff 100644
--- a/arch/sparc/kernel/pci_common.c
+++ b/arch/sparc/kernel/pci_common.c
@@ -328,41 +328,46 @@ void pci_get_pbm_props(struct pci_pbm_info *pbm)
 	}
 }
 
-static void pci_register_legacy_regions(struct resource *io_res,
-					struct resource *mem_res)
+static void pci_register_region(struct pci_bus *bus, const char *name,
+				resource_size_t rstart, resource_size_t size)
 {
-	struct resource *p;
+	struct resource *res, *conflict, *bus_res;
+	struct pci_bus_region region;
 
-	/* VGA Video RAM. */
-	p = kzalloc(sizeof(*p), GFP_KERNEL);
-	if (!p)
+	res = kzalloc(sizeof(*res), GFP_KERNEL);
+	if (!res)
 		return;
 
-	p->name = "Video RAM area";
-	p->start = mem_res->start + 0xa0000UL;
-	p->end = p->start + 0x1ffffUL;
-	p->flags = IORESOURCE_BUSY;
-	request_resource(mem_res, p);
+	res->flags = IORESOURCE_MEM;
 
-	p = kzalloc(sizeof(*p), GFP_KERNEL);
-	if (!p)
+	region.start = rstart;
+	region.end = rstart + size - 1UL;
+	pcibios_bus_to_resource(bus, res, &region);
+	bus_res = pci_find_bus_resource(bus, res);
+	if (!bus_res) {
+		kfree(res);
 		return;
+	}
+
+	res->name = name;
+	res->flags |= IORESOURCE_BUSY;
+	conflict = request_resource_conflict(bus_res, res);
+	if (conflict) {
+		dev_printk(KERN_DEBUG, &bus->dev,
+			" can't claim %s %pR: address conflict with %s %pR\n",
+			res->name, res, conflict->name, conflict);
+		kfree(res);
+	}
+}
 
-	p->name = "System ROM";
-	p->start = mem_res->start + 0xf0000UL;
-	p->end = p->start + 0xffffUL;
-	p->flags = IORESOURCE_BUSY;
-	request_resource(mem_res, p);
+void pci_register_legacy_regions(struct pci_bus *bus)
+{
+	/* VGA Video RAM. */
+	pci_register_region(bus, "Video RAM area", 0xa0000UL, 0x20000UL);
 
-	p = kzalloc(sizeof(*p), GFP_KERNEL);
-	if (!p)
-		return;
+	pci_register_region(bus, "System ROM",     0xf0000UL, 0x10000UL);
 
-	p->name = "Video ROM";
-	p->start = mem_res->start + 0xc0000UL;
-	p->end = p->start + 0x7fffUL;
-	p->flags = IORESOURCE_BUSY;
-	request_resource(mem_res, p);
+	pci_register_region(bus, "Video ROM",      0xc0000UL,  0x8000UL);
 }
 
 static void pci_register_iommu_region(struct pci_pbm_info *pbm)
@@ -504,8 +509,6 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
 	if (pbm->mem64_space.flags)
 		request_resource(&iomem_resource, &pbm->mem64_space);
 
-	pci_register_legacy_regions(&pbm->io_space,
-				    &pbm->mem_space);
 	pci_register_iommu_region(pbm);
 }
 
diff --git a/arch/sparc/kernel/pci_impl.h b/arch/sparc/kernel/pci_impl.h
index 2853af7..ff8f5e1 100644
--- a/arch/sparc/kernel/pci_impl.h
+++ b/arch/sparc/kernel/pci_impl.h
@@ -167,6 +167,7 @@ void pci_get_pbm_props(struct pci_pbm_info *pbm);
 struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
 				 struct device *parent);
 void pci_determine_mem_io_space(struct pci_pbm_info *pbm);
+void pci_register_legacy_regions(struct pci_bus *bus);
 
 /* Error reporting support. */
 void pci_scan_for_target_abort(struct pci_pbm_info *, struct pci_bus *);
-- 
2.9.3


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

* [PATCH 04/13] sparc/PCI: Add IORESOURCE_MEM_64 for 64-bit resource in OF parsing
  2017-04-21  5:04 [PATCH 00/13] PCI: sparc related 64bit resource fixup Yinghai Lu
@ 2017-04-21  5:04   ` Yinghai Lu
  2017-04-21  5:04 ` [PATCH 02/13] PCI: Add pci_find_bus_resource() Yinghai Lu
                     ` (11 subsequent siblings)
  12 siblings, 0 replies; 33+ messages in thread
From: Yinghai Lu @ 2017-04-21  5:04 UTC (permalink / raw)
  To: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt
  Cc: Wei Yang, Khalid Aziz, linux-pci, linux-kernel, Yinghai Lu, sparclinux

For device resource with PREF bit setting under bridge 64-bit pref resource,
we need to make sure only set PREF for 64bit resource.

so this patch set IORESOUCE_MEM_64 for 64bit resource during OF device
resource flags parsing.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=96261
Link: https://bugzilla.kernel.org/show_bug.cgi?id=96241
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: sparclinux@vger.kernel.org
Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
---
 arch/sparc/kernel/of_device_32.c | 5 +++--
 arch/sparc/kernel/of_device_64.c | 5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c
index 185aa96..3e9f273 100644
--- a/arch/sparc/kernel/of_device_32.c
+++ b/arch/sparc/kernel/of_device_32.c
@@ -83,11 +83,12 @@ static unsigned long of_bus_pci_get_flags(const u32 *addr, unsigned long flags)
 	case 0x01:
 		flags |= IORESOURCE_IO;
 		break;
-
 	case 0x02: /* 32 bits */
-	case 0x03: /* 64 bits */
 		flags |= IORESOURCE_MEM;
 		break;
+	case 0x03: /* 64 bits */
+		flags |= IORESOURCE_MEM | IORESOURCE_MEM_64;
+		break;
 	}
 	if (w & 0x40000000)
 		flags |= IORESOURCE_PREFETCH;
diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c
index 7bbdc26..defee61 100644
--- a/arch/sparc/kernel/of_device_64.c
+++ b/arch/sparc/kernel/of_device_64.c
@@ -146,11 +146,12 @@ static unsigned long of_bus_pci_get_flags(const u32 *addr, unsigned long flags)
 	case 0x01:
 		flags |= IORESOURCE_IO;
 		break;
-
 	case 0x02: /* 32 bits */
-	case 0x03: /* 64 bits */
 		flags |= IORESOURCE_MEM;
 		break;
+	case 0x03: /* 64 bits */
+		flags |= IORESOURCE_MEM | IORESOURCE_MEM_64;
+		break;
 	}
 	if (w & 0x40000000)
 		flags |= IORESOURCE_PREFETCH;
-- 
2.9.3

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

* [PATCH 04/13] sparc/PCI: Add IORESOURCE_MEM_64 for 64-bit resource in OF parsing
@ 2017-04-21  5:04   ` Yinghai Lu
  0 siblings, 0 replies; 33+ messages in thread
From: Yinghai Lu @ 2017-04-21  5:04 UTC (permalink / raw)
  To: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt
  Cc: Wei Yang, Khalid Aziz, linux-pci, linux-kernel, Yinghai Lu, sparclinux

For device resource with PREF bit setting under bridge 64-bit pref resource,
we need to make sure only set PREF for 64bit resource.

so this patch set IORESOUCE_MEM_64 for 64bit resource during OF device
resource flags parsing.

Link: https://bugzilla.kernel.org/show_bug.cgi?id–261
Link: https://bugzilla.kernel.org/show_bug.cgi?id–241
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: sparclinux@vger.kernel.org
Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
---
 arch/sparc/kernel/of_device_32.c | 5 +++--
 arch/sparc/kernel/of_device_64.c | 5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c
index 185aa96..3e9f273 100644
--- a/arch/sparc/kernel/of_device_32.c
+++ b/arch/sparc/kernel/of_device_32.c
@@ -83,11 +83,12 @@ static unsigned long of_bus_pci_get_flags(const u32 *addr, unsigned long flags)
 	case 0x01:
 		flags |= IORESOURCE_IO;
 		break;
-
 	case 0x02: /* 32 bits */
-	case 0x03: /* 64 bits */
 		flags |= IORESOURCE_MEM;
 		break;
+	case 0x03: /* 64 bits */
+		flags |= IORESOURCE_MEM | IORESOURCE_MEM_64;
+		break;
 	}
 	if (w & 0x40000000)
 		flags |= IORESOURCE_PREFETCH;
diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c
index 7bbdc26..defee61 100644
--- a/arch/sparc/kernel/of_device_64.c
+++ b/arch/sparc/kernel/of_device_64.c
@@ -146,11 +146,12 @@ static unsigned long of_bus_pci_get_flags(const u32 *addr, unsigned long flags)
 	case 0x01:
 		flags |= IORESOURCE_IO;
 		break;
-
 	case 0x02: /* 32 bits */
-	case 0x03: /* 64 bits */
 		flags |= IORESOURCE_MEM;
 		break;
+	case 0x03: /* 64 bits */
+		flags |= IORESOURCE_MEM | IORESOURCE_MEM_64;
+		break;
 	}
 	if (w & 0x40000000)
 		flags |= IORESOURCE_PREFETCH;
-- 
2.9.3


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

* [PATCH 05/13] sparc/PCI: Keep resource idx order with bridge register number
  2017-04-21  5:04 [PATCH 00/13] PCI: sparc related 64bit resource fixup Yinghai Lu
@ 2017-04-21  5:04   ` Yinghai Lu
  2017-04-21  5:04 ` [PATCH 02/13] PCI: Add pci_find_bus_resource() Yinghai Lu
                     ` (11 subsequent siblings)
  12 siblings, 0 replies; 33+ messages in thread
From: Yinghai Lu @ 2017-04-21  5:04 UTC (permalink / raw)
  To: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt
  Cc: Wei Yang, Khalid Aziz, linux-pci, linux-kernel, Yinghai Lu, sparclinux

On one system found strange "no compatible bridge window" warning
even we already had pref_compat support that add extra pref bit for device
resource.

PCI: Claiming 0000:00:01.0: Resource 14: 0002000100000000..000200010fffffff [10220c]
PCI: Claiming 0000:01:00.0: Resource 1: 0002000100000000..000200010000ffff [100214]
pci 0000:01:00.0: can't claim BAR 1 [mem 0x2000100000000-0x200010000ffff 64bit]: no compatible bridge window

It turns out that pci_resource_compatible()/pci_up_path_over_pref_mem64()
just check resource with bridge pref mmio register idx 15, and we have put
resource to use mmio register idx 14 during of_scan_pci_bridge()
as the bridge does not have mmio resource.

We already fix pci_up_path_over_pref_mem64() to check all bus resources.

And at the same time, this patch make resource to have consistent sequence
like other arch or directly from pci_read_bridge_bases(),
even when non-pref mmio is missing, or out of ordering in firmware reporting.

Just hold i = 1 for non pref mmio, and i = 2 for pref mmio.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
Cc: sparclinux@vger.kernel.org
---
 arch/sparc/kernel/pci.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index adb9653..887441e 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -481,7 +481,7 @@ static void of_scan_pci_bridge(struct pci_pbm_info *pbm,
 		pci_read_bridge_bases(bus);
 		goto after_ranges;
 	}
-	i = 1;
+	i = 3;
 	for (; len >= 32; len -= 32, ranges += 8) {
 		u64 start;
 
@@ -513,6 +513,12 @@ static void of_scan_pci_bridge(struct pci_pbm_info *pbm,
 				       " for bridge %s\n", node->full_name);
 				continue;
 			}
+		} else if ((flags & IORESOURCE_PREFETCH) &&
+			   !bus->resource[2]->flags) {
+			res = bus->resource[2];
+		} else if (((flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH)) ==
+			    IORESOURCE_MEM) && !bus->resource[1]->flags) {
+			res = bus->resource[1];
 		} else {
 			if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) {
 				printk(KERN_ERR "PCI: too many memory ranges"
-- 
2.9.3

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

* [PATCH 05/13] sparc/PCI: Keep resource idx order with bridge register number
@ 2017-04-21  5:04   ` Yinghai Lu
  0 siblings, 0 replies; 33+ messages in thread
From: Yinghai Lu @ 2017-04-21  5:04 UTC (permalink / raw)
  To: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt
  Cc: Wei Yang, Khalid Aziz, linux-pci, linux-kernel, Yinghai Lu, sparclinux

On one system found strange "no compatible bridge window" warning
even we already had pref_compat support that add extra pref bit for device
resource.

PCI: Claiming 0000:00:01.0: Resource 14: 0002000100000000..000200010fffffff [10220c]
PCI: Claiming 0000:01:00.0: Resource 1: 0002000100000000..000200010000ffff [100214]
pci 0000:01:00.0: can't claim BAR 1 [mem 0x2000100000000-0x200010000ffff 64bit]: no compatible bridge window

It turns out that pci_resource_compatible()/pci_up_path_over_pref_mem64()
just check resource with bridge pref mmio register idx 15, and we have put
resource to use mmio register idx 14 during of_scan_pci_bridge()
as the bridge does not have mmio resource.

We already fix pci_up_path_over_pref_mem64() to check all bus resources.

And at the same time, this patch make resource to have consistent sequence
like other arch or directly from pci_read_bridge_bases(),
even when non-pref mmio is missing, or out of ordering in firmware reporting.

Just hold i = 1 for non pref mmio, and i = 2 for pref mmio.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
Cc: sparclinux@vger.kernel.org
---
 arch/sparc/kernel/pci.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index adb9653..887441e 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -481,7 +481,7 @@ static void of_scan_pci_bridge(struct pci_pbm_info *pbm,
 		pci_read_bridge_bases(bus);
 		goto after_ranges;
 	}
-	i = 1;
+	i = 3;
 	for (; len >= 32; len -= 32, ranges += 8) {
 		u64 start;
 
@@ -513,6 +513,12 @@ static void of_scan_pci_bridge(struct pci_pbm_info *pbm,
 				       " for bridge %s\n", node->full_name);
 				continue;
 			}
+		} else if ((flags & IORESOURCE_PREFETCH) &&
+			   !bus->resource[2]->flags) {
+			res = bus->resource[2];
+		} else if (((flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH)) =
+			    IORESOURCE_MEM) && !bus->resource[1]->flags) {
+			res = bus->resource[1];
 		} else {
 			if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) {
 				printk(KERN_ERR "PCI: too many memory ranges"
-- 
2.9.3


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

* [PATCH 06/13] powerpc/PCI: Keep resource idx order with bridge register number
  2017-04-21  5:04 [PATCH 00/13] PCI: sparc related 64bit resource fixup Yinghai Lu
                   ` (4 preceding siblings ...)
  2017-04-21  5:04   ` Yinghai Lu
@ 2017-04-21  5:04 ` Yinghai Lu
  2017-04-21  5:04 ` [PATCH 07/13] powerpc/PCI: Add IORESOURCE_MEM_64 for 64-bit resource in OF parsing Yinghai Lu
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 33+ messages in thread
From: Yinghai Lu @ 2017-04-21  5:04 UTC (permalink / raw)
  To: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt
  Cc: Wei Yang, Khalid Aziz, linux-pci, linux-kernel, Yinghai Lu, linuxppc-dev

Same as sparc version.

Make resource with consistent sequence
like other arch or directly from pci_read_bridge_bases(),
even when non-pref mmio is missing, or out of ordering in firmware reporting.

Just hold i = 1 for non pref mmio, and i = 2 for pref mmio.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/kernel/pci_of_scan.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c
index ea3d981..9581e00 100644
--- a/arch/powerpc/kernel/pci_of_scan.c
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -252,7 +252,7 @@ void of_scan_pci_bridge(struct pci_dev *dev)
 		bus->resource[i] = res;
 		++res;
 	}
-	i = 1;
+	i = 3;
 	for (; len >= 32; len -= 32, ranges += 8) {
 		flags = pci_parse_of_flags(of_read_number(ranges, 1), 1);
 		size = of_read_number(&ranges[6], 2);
@@ -265,6 +265,12 @@ void of_scan_pci_bridge(struct pci_dev *dev)
 				       " for bridge %s\n", node->full_name);
 				continue;
 			}
+		} else if ((flags & IORESOURCE_PREFETCH) &&
+			   !bus->resource[2]->flags) {
+			res = bus->resource[2];
+		} else if (((flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH)) ==
+			    IORESOURCE_MEM) && !bus->resource[1]->flags) {
+			res = bus->resource[1];
 		} else {
 			if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) {
 				printk(KERN_ERR "PCI: too many memory ranges"
-- 
2.9.3

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

* [PATCH 07/13] powerpc/PCI: Add IORESOURCE_MEM_64 for 64-bit resource in OF parsing
  2017-04-21  5:04 [PATCH 00/13] PCI: sparc related 64bit resource fixup Yinghai Lu
                   ` (5 preceding siblings ...)
  2017-04-21  5:04 ` [PATCH 06/13] powerpc/PCI: " Yinghai Lu
@ 2017-04-21  5:04 ` Yinghai Lu
  2017-04-21  5:04 ` [PATCH 08/13] OF/PCI: Add IORESOURCE_MEM_64 for 64-bit resource Yinghai Lu
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 33+ messages in thread
From: Yinghai Lu @ 2017-04-21  5:04 UTC (permalink / raw)
  To: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt
  Cc: Wei Yang, Khalid Aziz, linux-pci, linux-kernel, Yinghai Lu,
	Paul Mackerras, Michael Ellerman, Gavin Shan, Yijing Wang,
	Anton Blanchard, linuxppc-dev

For device resource PREF bit setting under bridge 64-bit pref resource,
we need to make sure only set PREF for 64bit resource.

This patch set IORESOUCE_MEM_64 for 64bit resource during OF device
resource flags parsing.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=96261
Link: https://bugzilla.kernel.org/show_bug.cgi?id=96241
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Gavin Shan <gwshan@linux.vnet.ibm.com>
Cc: Yijing Wang <wangyijing@huawei.com>
Cc: Anton Blanchard <anton@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/kernel/pci_of_scan.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c
index 9581e00..24714d4 100644
--- a/arch/powerpc/kernel/pci_of_scan.c
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -44,8 +44,10 @@ static unsigned int pci_parse_of_flags(u32 addr0, int bridge)
 
 	if (addr0 & 0x02000000) {
 		flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY;
-		flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64;
 		flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M;
+		if (addr0 & 0x01000000)
+			flags |= IORESOURCE_MEM_64
+				 | PCI_BASE_ADDRESS_MEM_TYPE_64;
 		if (addr0 & 0x40000000)
 			flags |= IORESOURCE_PREFETCH
 				 | PCI_BASE_ADDRESS_MEM_PREFETCH;
-- 
2.9.3

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

* [PATCH 08/13] OF/PCI: Add IORESOURCE_MEM_64 for 64-bit resource
  2017-04-21  5:04 [PATCH 00/13] PCI: sparc related 64bit resource fixup Yinghai Lu
                   ` (6 preceding siblings ...)
  2017-04-21  5:04 ` [PATCH 07/13] powerpc/PCI: Add IORESOURCE_MEM_64 for 64-bit resource in OF parsing Yinghai Lu
@ 2017-04-21  5:04 ` Yinghai Lu
  2017-04-24 14:12     ` Rob Herring
  2017-04-21  5:04   ` Yinghai Lu
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 33+ messages in thread
From: Yinghai Lu @ 2017-04-21  5:04 UTC (permalink / raw)
  To: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt
  Cc: Wei Yang, Khalid Aziz, linux-pci, linux-kernel, Yinghai Lu,
	Grant Likely, Rob Herring, devicetree

For device resource PREF bit setting under bridge 64-bit pref resource,
we need to make sure only set PREF for 64bit resource.

This patch set IORESOUCE_MEM_64 for 64bit resource during OF device
resource flags parsing.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=96261
Link: https://bugzilla.kernel.org/show_bug.cgi?id=96241
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Grant Likely <grant.likely@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: devicetree@vger.kernel.org
Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
---
 drivers/of/address.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/of/address.c b/drivers/of/address.c
index 02b2903..d1bb76c 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -131,9 +131,11 @@ static unsigned int of_bus_pci_get_flags(const __be32 *addr)
 		flags |= IORESOURCE_IO;
 		break;
 	case 0x02: /* 32 bits */
-	case 0x03: /* 64 bits */
 		flags |= IORESOURCE_MEM;
 		break;
+	case 0x03: /* 64 bits */
+		flags |= IORESOURCE_MEM | IORESOURCE_MEM_64;
+		break;
 	}
 	if (w & 0x40000000)
 		flags |= IORESOURCE_PREFETCH;
-- 
2.9.3

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

* [PATCH 09/13] PCI: Check pref compatible bit for mem64 resource of PCIe device
  2017-04-21  5:04 [PATCH 00/13] PCI: sparc related 64bit resource fixup Yinghai Lu
@ 2017-04-21  5:04   ` Yinghai Lu
  2017-04-21  5:04 ` [PATCH 02/13] PCI: Add pci_find_bus_resource() Yinghai Lu
                     ` (11 subsequent siblings)
  12 siblings, 0 replies; 33+ messages in thread
From: Yinghai Lu @ 2017-04-21  5:04 UTC (permalink / raw)
  To: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt
  Cc: Wei Yang, Khalid Aziz, linux-pci, linux-kernel, Yinghai Lu, sparclinux

We still get "no compatible bridge window" warning on sparc T5-8
after we add support for 64bit resource parsing for root bus.

 PCI: scan_bus[/pci@300/pci@1/pci@0/pci@6] bus no 8
 PCI: Claiming 0000:00:01.0: Resource 15: 0000800100000000..00008004afffffff [220c]
 PCI: Claiming 0000:01:00.0: Resource 15: 0000800100000000..00008004afffffff [220c]
 PCI: Claiming 0000:02:04.0: Resource 15: 0000800100000000..000080012fffffff [220c]
 PCI: Claiming 0000:03:00.0: Resource 15: 0000800100000000..000080012fffffff [220c]
 PCI: Claiming 0000:04:06.0: Resource 14: 0000800100000000..000080010fffffff [220c]
 PCI: Claiming 0000:05:00.0: Resource 0: 0000800100000000..0000800100001fff [204]
 pci 0000:05:00.0: can't claim BAR 0 [mem 0x800100000000-0x800100001fff]: no compatible bridge window

All the bridges 64-bit resource have pref bit, but the device resource does not
have pref set, then we can not find parent for the device resource,
as we can not put non-pref mmio under pref mmio.

According to pcie spec errta
https://www.pcisig.com/specifications/pciexpress/base2/PCIe_Base_r2.1_Errata_08Jun10.pdf
page 13, in some case it is ok to mark some as pref.

Mark if the entire path from the host to the adapter is over PCI Express.
Set pref compatible bit for claim/sizing/assign for 64bit mem resource
on that pcie device.

-v2: set pref for mmio 64 when whole path is PCI Express, according to David Miller.
-v3: don't set pref directly, change to UNDER_PREF, and set PREF before
     sizing and assign resource, and cleart PREF afterwards. requested by BenH.
-v4: use on_all_pcie_path device flag instead.
-v6: update after pci_find_bus_resource() change

Link: http://lkml.kernel.org/r/CAE9FiQU1gJY1LYrxs+ma5LCTEEe4xmtjRG0aXJ9K_Tsu+m9Wuw@mail.gmail.com
Reported-by: David Ahern <david.ahern@oracle.com>
Tested-by: David Ahern <david.ahern@oracle.com>
Link: https://bugzilla.kernel.org/show_bug.cgi?id=81431
Tested-by: TJ <linux@iam.tj>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
Cc: sparclinux@vger.kernel.org
---
 arch/sparc/kernel/pci_common.c |  2 +-
 drivers/pci/pci.c              |  8 +++++---
 drivers/pci/pci.h              |  2 ++
 drivers/pci/probe.c            | 33 +++++++++++++++++++++++++++++++++
 drivers/pci/setup-bus.c        | 23 +++++++++++++++++++----
 drivers/pci/setup-res.c        |  4 ++++
 include/linux/pci.h            |  3 ++-
 7 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c
index 1ebc7ff..6f206a1 100644
--- a/arch/sparc/kernel/pci_common.c
+++ b/arch/sparc/kernel/pci_common.c
@@ -343,7 +343,7 @@ static void pci_register_region(struct pci_bus *bus, const char *name,
 	region.start = rstart;
 	region.end = rstart + size - 1UL;
 	pcibios_bus_to_resource(bus, res, &region);
-	bus_res = pci_find_bus_resource(bus, res);
+	bus_res = pci_find_bus_resource(bus, res, res->flags);
 	if (!bus_res) {
 		kfree(res);
 		return;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index deb828f..bdb70b7 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -438,7 +438,7 @@ int pci_find_ht_capability(struct pci_dev *dev, int ht_cap)
 EXPORT_SYMBOL_GPL(pci_find_ht_capability);
 
 struct resource *pci_find_bus_resource(const struct pci_bus *bus,
-					struct resource *res)
+					struct resource *res, int flags)
 {
 	struct resource *r;
 	int i;
@@ -453,7 +453,7 @@ struct resource *pci_find_bus_resource(const struct pci_bus *bus,
 			 * not, the allocator made a mistake.
 			 */
 			if (r->flags & IORESOURCE_PREFETCH &&
-			    !(res->flags & IORESOURCE_PREFETCH))
+			    !(flags & IORESOURCE_PREFETCH))
 				return NULL;
 
 			/*
@@ -481,7 +481,9 @@ struct resource *pci_find_bus_resource(const struct pci_bus *bus,
 struct resource *pci_find_parent_resource(const struct pci_dev *dev,
 					  struct resource *res)
 {
-	return pci_find_bus_resource(dev->bus, res);
+	int flags = pci_resource_pref_compatible(dev, res);
+
+	return pci_find_bus_resource(dev->bus, res, flags);
 }
 EXPORT_SYMBOL(pci_find_parent_resource);
 
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 586e63f..eb57780 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -368,4 +368,6 @@ int acpi_get_rc_resources(struct device *dev, const char *hid, u16 segment,
 			  struct resource *res);
 #endif
 
+int pci_resource_pref_compatible(const struct pci_dev *dev,
+				 struct resource *res);
 #endif /* DRIVERS_PCI_H */
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 5548044..676b55f 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1920,6 +1920,36 @@ static void pci_dma_configure(struct pci_dev *dev)
 	pci_put_host_bridge_device(bridge);
 }
 
+static bool pci_up_path_over_pcie(struct pci_bus *bus)
+{
+	if (pci_is_root_bus(bus))
+		return true;
+
+	if (bus->self && !pci_is_pcie(bus->self))
+		return false;
+
+	return pci_up_path_over_pcie(bus->parent);
+}
+
+/*
+ * According to
+ * https://www.pcisig.com/specifications/pciexpress/base2/PCIe_Base_r2.1_Errata_08Jun10.pdf
+ * page 13, system firmware could put some 64bit non-pref under 64bit pref,
+ * on some cases.
+ * Let's mark if entire path from the host to the adapter is over PCI
+ * Express. later will use that compute pref compaitable bit.
+ */
+static void pci_set_on_all_pcie_path(struct pci_dev *dev)
+{
+	if (!pci_is_pcie(dev))
+		return;
+
+	if (!pci_up_path_over_pcie(dev->bus))
+		return;
+
+	dev->on_all_pcie_path = 1;
+}
+
 void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 {
 	int ret;
@@ -1950,6 +1980,9 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 	/* Initialize various capabilities */
 	pci_init_capabilities(dev);
 
+	/* After pcie_cap is assigned */
+	pci_set_on_all_pcie_path(dev);
+
 	/*
 	 * Add the device to our list of discovered devices
 	 * and the bus list for fixup functions, etc.
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 958da7d..3de66e6 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -735,6 +735,20 @@ int pci_claim_bridge_resource(struct pci_dev *bridge, int i)
 	return -EINVAL;
 }
 
+int pci_resource_pref_compatible(const struct pci_dev *dev,
+				 struct resource *res)
+{
+	if (res->flags & IORESOURCE_PREFETCH)
+		return res->flags;
+
+	if ((res->flags & IORESOURCE_MEM) &&
+	    (res->flags & IORESOURCE_MEM_64) &&
+	    dev->on_all_pcie_path)
+		return res->flags | IORESOURCE_PREFETCH;
+
+	return res->flags;
+}
+
 /* Check whether the bridge supports optional I/O and
    prefetchable memory ranges. If not, the respective
    base/limit registers must be read-only and read as 0. */
@@ -1032,11 +1046,12 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
 		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
 			struct resource *r = &dev->resource[i];
 			resource_size_t r_size;
+			int flags = pci_resource_pref_compatible(dev, r);
 
-			if (r->parent || (r->flags & IORESOURCE_PCI_FIXED) ||
-			    ((r->flags & mask) != type &&
-			     (r->flags & mask) != type2 &&
-			     (r->flags & mask) != type3))
+			if (r->parent || (flags & IORESOURCE_PCI_FIXED) ||
+			    ((flags & mask) != type &&
+			     (flags & mask) != type2 &&
+			     (flags & mask) != type3))
 				continue;
 			r_size = resource_size(r);
 #ifdef CONFIG_PCI_IOV
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 85774b7..2aeb4bc 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -285,15 +285,19 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
 static int _pci_assign_resource(struct pci_dev *dev, int resno,
 				resource_size_t size, resource_size_t min_align)
 {
+	struct resource *res = dev->resource + resno;
+	int old_flags = res->flags;
 	struct pci_bus *bus;
 	int ret;
 
+	res->flags = pci_resource_pref_compatible(dev, res);
 	bus = dev->bus;
 	while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) {
 		if (!bus->parent || !bus->self->transparent)
 			break;
 		bus = bus->parent;
 	}
+	res->flags = old_flags;
 
 	return ret;
 }
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 817786b..b14dd94 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -321,6 +321,7 @@ struct pci_dev {
 	unsigned int	hotplug_user_indicators:1; /* SlotCtl indicators
 						      controlled exclusively by
 						      user sysfs */
+	unsigned int	on_all_pcie_path:1;	/* up to host-bridge all pcie */
 	unsigned int	d3_delay;	/* D3->D0 transition time in ms */
 	unsigned int	d3cold_delay;	/* D3cold->D0 transition time in ms */
 
@@ -837,7 +838,7 @@ void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,
 void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res,
 			     struct pci_bus_region *region);
 struct resource *pci_find_bus_resource(const struct pci_bus *bus,
-					struct resource *res);
+					struct resource *res, int flags);
 void pcibios_scan_specific_bus(int busn);
 struct pci_bus *pci_find_bus(int domain, int busnr);
 void pci_bus_add_devices(const struct pci_bus *bus);
-- 
2.9.3

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

* [PATCH 09/13] PCI: Check pref compatible bit for mem64 resource of PCIe device
@ 2017-04-21  5:04   ` Yinghai Lu
  0 siblings, 0 replies; 33+ messages in thread
From: Yinghai Lu @ 2017-04-21  5:04 UTC (permalink / raw)
  To: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt
  Cc: Wei Yang, Khalid Aziz, linux-pci, linux-kernel, Yinghai Lu, sparclinux

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="windows-1254", Size: 9295 bytes --]

We still get "no compatible bridge window" warning on sparc T5-8
after we add support for 64bit resource parsing for root bus.

 PCI: scan_bus[/pci@300/pci@1/pci@0/pci@6] bus no 8
 PCI: Claiming 0000:00:01.0: Resource 15: 0000800100000000..00008004afffffff [220c]
 PCI: Claiming 0000:01:00.0: Resource 15: 0000800100000000..00008004afffffff [220c]
 PCI: Claiming 0000:02:04.0: Resource 15: 0000800100000000..000080012fffffff [220c]
 PCI: Claiming 0000:03:00.0: Resource 15: 0000800100000000..000080012fffffff [220c]
 PCI: Claiming 0000:04:06.0: Resource 14: 0000800100000000..000080010fffffff [220c]
 PCI: Claiming 0000:05:00.0: Resource 0: 0000800100000000..0000800100001fff [204]
 pci 0000:05:00.0: can't claim BAR 0 [mem 0x800100000000-0x800100001fff]: no compatible bridge window

All the bridges 64-bit resource have pref bit, but the device resource does not
have pref set, then we can not find parent for the device resource,
as we can not put non-pref mmio under pref mmio.

According to pcie spec errta
https://www.pcisig.com/specifications/pciexpress/base2/PCIe_Base_r2.1_Errata_08Jun10.pdf
page 13, in some case it is ok to mark some as pref.

Mark if the entire path from the host to the adapter is over PCI Express.
Set pref compatible bit for claim/sizing/assign for 64bit mem resource
on that pcie device.

-v2: set pref for mmio 64 when whole path is PCI Express, according to David Miller.
-v3: don't set pref directly, change to UNDER_PREF, and set PREF before
     sizing and assign resource, and cleart PREF afterwards. requested by BenH.
-v4: use on_all_pcie_path device flag instead.
-v6: update after pci_find_bus_resource() change

Link: http://lkml.kernel.org/r/CAE9FiQU1gJY1LYrxs+ma5LCTEEe4xmtjRG0aXJ9K_Tsu+m9Wuw@mail.gmail.com
Reported-by: David Ahern <david.ahern@oracle.com>
Tested-by: David Ahern <david.ahern@oracle.com>
Link: https://bugzilla.kernel.org/show_bug.cgi?id431
Tested-by: TJ <linux@iam.tj>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
Cc: sparclinux@vger.kernel.org
---
 arch/sparc/kernel/pci_common.c |  2 +-
 drivers/pci/pci.c              |  8 +++++---
 drivers/pci/pci.h              |  2 ++
 drivers/pci/probe.c            | 33 +++++++++++++++++++++++++++++++++
 drivers/pci/setup-bus.c        | 23 +++++++++++++++++++----
 drivers/pci/setup-res.c        |  4 ++++
 include/linux/pci.h            |  3 ++-
 7 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c
index 1ebc7ff..6f206a1 100644
--- a/arch/sparc/kernel/pci_common.c
+++ b/arch/sparc/kernel/pci_common.c
@@ -343,7 +343,7 @@ static void pci_register_region(struct pci_bus *bus, const char *name,
 	region.start = rstart;
 	region.end = rstart + size - 1UL;
 	pcibios_bus_to_resource(bus, res, &region);
-	bus_res = pci_find_bus_resource(bus, res);
+	bus_res = pci_find_bus_resource(bus, res, res->flags);
 	if (!bus_res) {
 		kfree(res);
 		return;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index deb828f..bdb70b7 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -438,7 +438,7 @@ int pci_find_ht_capability(struct pci_dev *dev, int ht_cap)
 EXPORT_SYMBOL_GPL(pci_find_ht_capability);
 
 struct resource *pci_find_bus_resource(const struct pci_bus *bus,
-					struct resource *res)
+					struct resource *res, int flags)
 {
 	struct resource *r;
 	int i;
@@ -453,7 +453,7 @@ struct resource *pci_find_bus_resource(const struct pci_bus *bus,
 			 * not, the allocator made a mistake.
 			 */
 			if (r->flags & IORESOURCE_PREFETCH &&
-			    !(res->flags & IORESOURCE_PREFETCH))
+			    !(flags & IORESOURCE_PREFETCH))
 				return NULL;
 
 			/*
@@ -481,7 +481,9 @@ struct resource *pci_find_bus_resource(const struct pci_bus *bus,
 struct resource *pci_find_parent_resource(const struct pci_dev *dev,
 					  struct resource *res)
 {
-	return pci_find_bus_resource(dev->bus, res);
+	int flags = pci_resource_pref_compatible(dev, res);
+
+	return pci_find_bus_resource(dev->bus, res, flags);
 }
 EXPORT_SYMBOL(pci_find_parent_resource);
 
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 586e63f..eb57780 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -368,4 +368,6 @@ int acpi_get_rc_resources(struct device *dev, const char *hid, u16 segment,
 			  struct resource *res);
 #endif
 
+int pci_resource_pref_compatible(const struct pci_dev *dev,
+				 struct resource *res);
 #endif /* DRIVERS_PCI_H */
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 5548044..676b55f 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1920,6 +1920,36 @@ static void pci_dma_configure(struct pci_dev *dev)
 	pci_put_host_bridge_device(bridge);
 }
 
+static bool pci_up_path_over_pcie(struct pci_bus *bus)
+{
+	if (pci_is_root_bus(bus))
+		return true;
+
+	if (bus->self && !pci_is_pcie(bus->self))
+		return false;
+
+	return pci_up_path_over_pcie(bus->parent);
+}
+
+/*
+ * According to
+ * https://www.pcisig.com/specifications/pciexpress/base2/PCIe_Base_r2.1_Errata_08Jun10.pdf
+ * page 13, system firmware could put some 64bit non-pref under 64bit pref,
+ * on some cases.
+ * Let's mark if entire path from the host to the adapter is over PCI
+ * Express. later will use that compute pref compaitable bit.
+ */
+static void pci_set_on_all_pcie_path(struct pci_dev *dev)
+{
+	if (!pci_is_pcie(dev))
+		return;
+
+	if (!pci_up_path_over_pcie(dev->bus))
+		return;
+
+	dev->on_all_pcie_path = 1;
+}
+
 void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 {
 	int ret;
@@ -1950,6 +1980,9 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 	/* Initialize various capabilities */
 	pci_init_capabilities(dev);
 
+	/* After pcie_cap is assigned */
+	pci_set_on_all_pcie_path(dev);
+
 	/*
 	 * Add the device to our list of discovered devices
 	 * and the bus list for fixup functions, etc.
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 958da7d..3de66e6 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -735,6 +735,20 @@ int pci_claim_bridge_resource(struct pci_dev *bridge, int i)
 	return -EINVAL;
 }
 
+int pci_resource_pref_compatible(const struct pci_dev *dev,
+				 struct resource *res)
+{
+	if (res->flags & IORESOURCE_PREFETCH)
+		return res->flags;
+
+	if ((res->flags & IORESOURCE_MEM) &&
+	    (res->flags & IORESOURCE_MEM_64) &&
+	    dev->on_all_pcie_path)
+		return res->flags | IORESOURCE_PREFETCH;
+
+	return res->flags;
+}
+
 /* Check whether the bridge supports optional I/O and
    prefetchable memory ranges. If not, the respective
    base/limit registers must be read-only and read as 0. */
@@ -1032,11 +1046,12 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
 		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
 			struct resource *r = &dev->resource[i];
 			resource_size_t r_size;
+			int flags = pci_resource_pref_compatible(dev, r);
 
-			if (r->parent || (r->flags & IORESOURCE_PCI_FIXED) ||
-			    ((r->flags & mask) != type &&
-			     (r->flags & mask) != type2 &&
-			     (r->flags & mask) != type3))
+			if (r->parent || (flags & IORESOURCE_PCI_FIXED) ||
+			    ((flags & mask) != type &&
+			     (flags & mask) != type2 &&
+			     (flags & mask) != type3))
 				continue;
 			r_size = resource_size(r);
 #ifdef CONFIG_PCI_IOV
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 85774b7..2aeb4bc 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -285,15 +285,19 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
 static int _pci_assign_resource(struct pci_dev *dev, int resno,
 				resource_size_t size, resource_size_t min_align)
 {
+	struct resource *res = dev->resource + resno;
+	int old_flags = res->flags;
 	struct pci_bus *bus;
 	int ret;
 
+	res->flags = pci_resource_pref_compatible(dev, res);
 	bus = dev->bus;
 	while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) {
 		if (!bus->parent || !bus->self->transparent)
 			break;
 		bus = bus->parent;
 	}
+	res->flags = old_flags;
 
 	return ret;
 }
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 817786b..b14dd94 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -321,6 +321,7 @@ struct pci_dev {
 	unsigned int	hotplug_user_indicators:1; /* SlotCtl indicators
 						      controlled exclusively by
 						      user sysfs */
+	unsigned int	on_all_pcie_path:1;	/* up to host-bridge all pcie */
 	unsigned int	d3_delay;	/* D3->D0 transition time in ms */
 	unsigned int	d3cold_delay;	/* D3cold->D0 transition time in ms */
 
@@ -837,7 +838,7 @@ void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,
 void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res,
 			     struct pci_bus_region *region);
 struct resource *pci_find_bus_resource(const struct pci_bus *bus,
-					struct resource *res);
+					struct resource *res, int flags);
 void pcibios_scan_specific_bus(int busn);
 struct pci_bus *pci_find_bus(int domain, int busnr);
 void pci_bus_add_devices(const struct pci_bus *bus);
-- 
2.9.3

--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 10/13] PCI: Only treat non-pref mmio64 as pref if all bridges have MEM_64
  2017-04-21  5:04 [PATCH 00/13] PCI: sparc related 64bit resource fixup Yinghai Lu
                   ` (8 preceding siblings ...)
  2017-04-21  5:04   ` Yinghai Lu
@ 2017-04-21  5:04 ` Yinghai Lu
  2017-05-04 21:43   ` Bjorn Helgaas
  2017-04-21  5:04 ` [PATCH 11/13] PCI: Add has_mem64 for struct host_bridge Yinghai Lu
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 33+ messages in thread
From: Yinghai Lu @ 2017-04-21  5:04 UTC (permalink / raw)
  To: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt
  Cc: Wei Yang, Khalid Aziz, linux-pci, linux-kernel, Yinghai Lu

If any bridge up to root only have 32bit pref mmio, We don't need to
treat device non-pref mmio64 as as pref mmio64.

We need to move pci_bridge_check_ranges calling early.
For parent bridges pref mmio BAR may not allocated by BIOS, res flags
is still 0, we need to have it correct set before we check them for
child device resources.

-v2: check all bus resources instead of just res[15].

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
---
 drivers/pci/setup-bus.c | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 3de66e6..b3fd314 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -735,6 +735,29 @@ int pci_claim_bridge_resource(struct pci_dev *bridge, int i)
 	return -EINVAL;
 }
 
+static bool pci_up_path_over_pref_mem64(struct pci_bus *bus)
+{
+	if (pci_is_root_bus(bus))
+		return true;
+
+	if (bus->self) {
+		int i;
+		bool found = false;
+		struct resource *res;
+
+		pci_bus_for_each_resource(bus, res, i)
+			if (res->flags & IORESOURCE_MEM_64) {
+				found = true;
+				break;
+			}
+
+		if (!found)
+			return false;
+	}
+
+	return pci_up_path_over_pref_mem64(bus->parent);
+}
+
 int pci_resource_pref_compatible(const struct pci_dev *dev,
 				 struct resource *res)
 {
@@ -743,7 +766,8 @@ int pci_resource_pref_compatible(const struct pci_dev *dev,
 
 	if ((res->flags & IORESOURCE_MEM) &&
 	    (res->flags & IORESOURCE_MEM_64) &&
-	    dev->on_all_pcie_path)
+	    dev->on_all_pcie_path &&
+	    pci_up_path_over_pref_mem64(dev->bus))
 		return res->flags | IORESOURCE_PREFETCH;
 
 	return res->flags;
@@ -1236,6 +1260,10 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head)
 	struct resource *b_res;
 	int ret;
 
+	if (!pci_is_root_bus(bus) &&
+	    (bus->self->class >> 8) == PCI_CLASS_BRIDGE_PCI)
+		pci_bridge_check_ranges(bus);
+
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		struct pci_bus *b = dev->subordinate;
 		if (!b)
@@ -1263,7 +1291,6 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head)
 		break;
 
 	case PCI_CLASS_BRIDGE_PCI:
-		pci_bridge_check_ranges(bus);
 		if (bus->self->is_hotplug_bridge) {
 			additional_io_size  = pci_hotplug_io_size;
 			additional_mem_size = pci_hotplug_mem_size;
-- 
2.9.3

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

* [PATCH 11/13] PCI: Add has_mem64 for struct host_bridge
  2017-04-21  5:04 [PATCH 00/13] PCI: sparc related 64bit resource fixup Yinghai Lu
                   ` (9 preceding siblings ...)
  2017-04-21  5:04 ` [PATCH 10/13] PCI: Only treat non-pref mmio64 as pref if all bridges have MEM_64 Yinghai Lu
@ 2017-04-21  5:04 ` Yinghai Lu
  2017-05-04 23:04   ` Bjorn Helgaas
  2017-04-21  5:04 ` [PATCH 12/13] PCI: Only treat non-pref mmio64 as pref if host bridge has mmio64 Yinghai Lu
  2017-04-21  5:05 ` [PATCH 13/13] PCI: Restore pref MMIO allocation logic for host bridge without mmio64 Yinghai Lu
  12 siblings, 1 reply; 33+ messages in thread
From: Yinghai Lu @ 2017-04-21  5:04 UTC (permalink / raw)
  To: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt
  Cc: Wei Yang, Khalid Aziz, linux-pci, linux-kernel, Yinghai Lu

Add has_mem64 for struct host_bridge, on root bus that does not support
mmio64 above 4g, will not set that.

We will use that info next two following patches:
1. Don't treat non-pref mmio64 as pref mmio, so will not put
   it under bridge's pref range when rescan the devices
2. will keep pref mmio64 and pref mmio32 under bridge pref bar.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
---
 drivers/pci/probe.c | 7 +++++++
 include/linux/pci.h | 1 +
 2 files changed, 8 insertions(+)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 676b55f..8f439e0 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -818,6 +818,13 @@ int pci_register_host_bridge(struct pci_host_bridge *bridge)
 			addr[0] = '\0';
 
 		dev_info(&bus->dev, "root bus resource %pR%s\n", res, addr);
+
+		if (resource_type(res) == IORESOURCE_MEM) {
+			if ((res->end - offset) > 0xffffffff)
+				bridge->has_mem64 = 1;
+			if ((res->start - offset) > 0xffffffff)
+				res->flags |= IORESOURCE_MEM_64;
+		}
 	}
 
 	down_write(&pci_bus_sem);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index b14dd94..a3693ef 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -436,6 +436,7 @@ struct pci_host_bridge {
 	void *release_data;
 	struct msi_controller *msi;
 	unsigned int ignore_reset_delay:1;	/* for entire hierarchy */
+	unsigned int has_mem64:1;
 	/* Resource alignment requirements */
 	resource_size_t (*align_resource)(struct pci_dev *dev,
 			const struct resource *res,
-- 
2.9.3

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

* [PATCH 12/13] PCI: Only treat non-pref mmio64 as pref if host bridge has mmio64
  2017-04-21  5:04 [PATCH 00/13] PCI: sparc related 64bit resource fixup Yinghai Lu
                   ` (10 preceding siblings ...)
  2017-04-21  5:04 ` [PATCH 11/13] PCI: Add has_mem64 for struct host_bridge Yinghai Lu
@ 2017-04-21  5:04 ` Yinghai Lu
  2017-04-21  5:05 ` [PATCH 13/13] PCI: Restore pref MMIO allocation logic for host bridge without mmio64 Yinghai Lu
  12 siblings, 0 replies; 33+ messages in thread
From: Yinghai Lu @ 2017-04-21  5:04 UTC (permalink / raw)
  To: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt
  Cc: Wei Yang, Khalid Aziz, linux-pci, linux-kernel, Yinghai Lu

If host bridge does not have mmio64 above 4G, We don't need to
treat device non-pref mmio64 as as pref mmio64.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
---
 drivers/pci/setup-bus.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index b3fd314..7a0e59b 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -738,7 +738,7 @@ int pci_claim_bridge_resource(struct pci_dev *bridge, int i)
 static bool pci_up_path_over_pref_mem64(struct pci_bus *bus)
 {
 	if (pci_is_root_bus(bus))
-		return true;
+		return to_pci_host_bridge(bus->bridge)->has_mem64;
 
 	if (bus->self) {
 		int i;
-- 
2.9.3

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

* [PATCH 13/13] PCI: Restore pref MMIO allocation logic for host bridge without mmio64
  2017-04-21  5:04 [PATCH 00/13] PCI: sparc related 64bit resource fixup Yinghai Lu
                   ` (11 preceding siblings ...)
  2017-04-21  5:04 ` [PATCH 12/13] PCI: Only treat non-pref mmio64 as pref if host bridge has mmio64 Yinghai Lu
@ 2017-04-21  5:05 ` Yinghai Lu
  2017-05-05  1:24   ` Bjorn Helgaas
  12 siblings, 1 reply; 33+ messages in thread
From: Yinghai Lu @ 2017-04-21  5:05 UTC (permalink / raw)
  To: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt
  Cc: Wei Yang, Khalid Aziz, linux-pci, linux-kernel, Yinghai Lu

>From 5b2854155 (PCI: Restrict 64-bit prefetchable bridge windows to 64-bit
resources), we change the logic for pref mmio allocation:
When bridge pref support mmio64, we will only put children pref
that support mmio64 into it, and will put children pref mmio32
into bridge's non-pref mmio32.

That could leave bridge pref bar not used when that pref bar is mmio64,
and children res only has mmio32.
Also could have allocation failure when non-pref mmio32 is not big
enough space for those children pref mmio32.

That is not rational when the host bridge does not have 64bit mmio
above 4g at all.

The patch restore to old logic:
when host bridge does not have has_mem64, put children pref mmio64 and
pref mmio32 all under bridges pref bars.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
---
 drivers/pci/bus.c       |  4 +++-
 drivers/pci/setup-bus.c | 13 +++++++++----
 drivers/pci/setup-res.c |  9 ++++++---
 3 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index bc56cf1..79205fb 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -233,8 +233,10 @@ int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
 {
 #ifdef CONFIG_PCI_BUS_ADDR_T_64BIT
 	int rc;
+	unsigned long mmio64 = pci_find_host_bridge(bus)->has_mem64 ?
+				IORESOURCE_MEM_64 : 0;
 
-	if (res->flags & IORESOURCE_MEM_64) {
+	if (res->flags & mmio64) {
 		rc = pci_bus_alloc_from_region(bus, res, size, align, min,
 					       type_mask, alignf, alignf_data,
 					       &pci_high);
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 7a0e59b..f29cf5d 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1308,7 +1308,8 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head)
 		b_res = &bus->self->resource[PCI_BRIDGE_RESOURCES];
 		mask = IORESOURCE_MEM;
 		prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH;
-		if (b_res[2].flags & IORESOURCE_MEM_64) {
+		if ((b_res[2].flags & IORESOURCE_MEM_64) &&
+		    pci_find_host_bridge(bus)->has_mem64) {
 			prefmask |= IORESOURCE_MEM_64;
 			ret = pbus_size_mem(bus, prefmask, prefmask,
 				  prefmask, prefmask,
@@ -1578,17 +1579,21 @@ static void pci_bridge_release_resources(struct pci_bus *bus,
 	 *	  io port.
 	 *     2. if there is non pref mmio assign fail, release bridge
 	 *	  nonpref mmio.
-	 *     3. if there is 64bit pref mmio assign fail, and bridge pref
+	 *     3. if there is pref mmio assign fail, and host bridge does
+	 *	  have 64bit mmio, release bridge pref mmio.
+	 *     4. if there is 64bit pref mmio assign fail, and bridge pref
 	 *	  is 64bit, release bridge pref mmio.
-	 *     4. if there is pref mmio assign fail, and bridge pref is
+	 *     5. if there is pref mmio assign fail, and bridge pref is
 	 *	  32bit mmio, release bridge pref mmio
-	 *     5. if there is pref mmio assign fail, and bridge pref is not
+	 *     6. if there is pref mmio assign fail, and bridge pref is not
 	 *	  assigned, release bridge nonpref mmio.
 	 */
 	if (type & IORESOURCE_IO)
 		idx = 0;
 	else if (!(type & IORESOURCE_PREFETCH))
 		idx = 1;
+	else if (!pci_find_host_bridge(bus)->has_mem64)
+		idx = 2;
 	else if ((type & IORESOURCE_MEM_64) &&
 		 (b_res[2].flags & IORESOURCE_MEM_64))
 		idx = 2;
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 2aeb4bc..49cfb55 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -240,6 +240,8 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
 	struct resource *res = dev->resource + resno;
 	resource_size_t min;
 	int ret;
+	unsigned long mmio64 = pci_find_host_bridge(bus)->has_mem64 ?
+				IORESOURCE_MEM_64 : 0;
 
 	min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
 
@@ -251,7 +253,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
 	 * things differently than they were sized, not everything will fit.
 	 */
 	ret = pci_bus_alloc_resource(bus, res, size, align, min,
-				     IORESOURCE_PREFETCH | IORESOURCE_MEM_64,
+				     IORESOURCE_PREFETCH | mmio64,
 				     pcibios_align_resource, dev);
 	if (ret == 0)
 		return 0;
@@ -260,7 +262,8 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
 	 * If the prefetchable window is only 32 bits wide, we can put
 	 * 64-bit prefetchable resources in it.
 	 */
-	if ((res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) ==
+	if (mmio64 &&
+	    (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) ==
 	     (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) {
 		ret = pci_bus_alloc_resource(bus, res, size, align, min,
 					     IORESOURCE_PREFETCH,
@@ -275,7 +278,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
 	 * non-prefetchable, the first call already tried the only possibility
 	 * so we don't need to try again.
 	 */
-	if (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64))
+	if (res->flags & (IORESOURCE_PREFETCH | mmio64))
 		ret = pci_bus_alloc_resource(bus, res, size, align, min, 0,
 					     pcibios_align_resource, dev);
 
-- 
2.9.3

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

* Re: [PATCH 08/13] OF/PCI: Add IORESOURCE_MEM_64 for 64-bit resource
@ 2017-04-24 14:12     ` Rob Herring
  0 siblings, 0 replies; 33+ messages in thread
From: Rob Herring @ 2017-04-24 14:12 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt, Wei Yang,
	Khalid Aziz, linux-pci, linux-kernel, Grant Likely, devicetree

On Fri, Apr 21, 2017 at 12:04 AM, Yinghai Lu <yinghai@kernel.org> wrote:
> For device resource PREF bit setting under bridge 64-bit pref resource,
> we need to make sure only set PREF for 64bit resource.
>
> This patch set IORESOUCE_MEM_64 for 64bit resource during OF device
> resource flags parsing.
>
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=96261
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=96241
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> Cc: Grant Likely <grant.likely@linaro.org>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: devicetree@vger.kernel.org
> Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
> ---
>  drivers/of/address.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)

Acked-by: Rob Herring <robh@kernel.org>

Rob

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

* Re: [PATCH 08/13] OF/PCI: Add IORESOURCE_MEM_64 for 64-bit resource
@ 2017-04-24 14:12     ` Rob Herring
  0 siblings, 0 replies; 33+ messages in thread
From: Rob Herring @ 2017-04-24 14:12 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt, Wei Yang,
	Khalid Aziz, linux-pci-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Grant Likely,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On Fri, Apr 21, 2017 at 12:04 AM, Yinghai Lu <yinghai-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> For device resource PREF bit setting under bridge 64-bit pref resource,
> we need to make sure only set PREF for 64bit resource.
>
> This patch set IORESOUCE_MEM_64 for 64bit resource during OF device
> resource flags parsing.
>
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=96261
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=96241
> Signed-off-by: Yinghai Lu <yinghai-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Cc: Grant Likely <grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Cc: Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Tested-by: Khalid Aziz <khalid.aziz-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>
> ---
>  drivers/of/address.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)

Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

Rob
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 03/13] sparc/PCI: Reserve legacy mmio after PCI mmio
  2017-04-21  5:04   ` Yinghai Lu
@ 2017-05-03 22:03     ` Bjorn Helgaas
  -1 siblings, 0 replies; 33+ messages in thread
From: Bjorn Helgaas @ 2017-05-03 22:03 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt, Wei Yang,
	Khalid Aziz, linux-pci, linux-kernel, sparclinux

On Thu, Apr 20, 2017 at 10:04:50PM -0700, Yinghai Lu wrote:
> On one system found bunch of claim resource fail from pci device.
> pci_sun4v f02b894c: PCI host bridge to bus 0000:00
> pci_bus 0000:00: root bus resource [io  0x2007e00000000-0x2007e0fffffff] (bus address [0x0000-0xfffffff])
> pci_bus 0000:00: root bus resource [mem 0x2000000000000-0x200007effffff] (bus address [0x00000000-0x7effffff])
> pci_bus 0000:00: root bus resource [mem 0x2000100000000-0x20007ffffffff] (bus address [0x100000000-0x7ffffffff])
> ...
> PCI: Claiming 0000:00:02.0: Resource 14: 0002000000000000..00020000004fffff [200]
> pci 0000:00:02.0: can't claim BAR 14 [mem 0x2000000000000-0x20000004fffff]: address conflict with Video RAM area [??? 0x20000000a0000-0x20000000bffff flags 0x80000000]
> pci 0000:02:00.0: can't claim BAR 0 [mem 0x2000000000000-0x20000000fffff]: no compatible bridge window
> PCI: Claiming 0000:02:00.0: Resource 3: 0002000000100000..0002000000103fff [200]
> pci 0000:02:00.0: can't claim BAR 3 [mem 0x2000000100000-0x2000000103fff]: no compatible bridge window
> PCI: Claiming 0000:02:00.1: Resource 0: 0002000000200000..00020000002fffff [200]
> pci 0000:02:00.1: can't claim BAR 0 [mem 0x2000000200000-0x20000002fffff]: no compatible bridge window
> PCI: Claiming 0000:02:00.1: Resource 3: 0002000000104000..0002000000107fff [200]
> pci 0000:02:00.1: can't claim BAR 3 [mem 0x2000000104000-0x2000000107fff]: no compatible bridge window
> PCI: Claiming 0000:02:00.2: Resource 0: 0002000000300000..00020000003fffff [200]
> pci 0000:02:00.2: can't claim BAR 0 [mem 0x2000000300000-0x20000003fffff]: no compatible bridge window
> PCI: Claiming 0000:02:00.2: Resource 3: 0002000000108000..000200000010bfff [200]
> pci 0000:02:00.2: can't claim BAR 3 [mem 0x2000000108000-0x200000010bfff]: no compatible bridge window
> PCI: Claiming 0000:02:00.3: Resource 0: 0002000000400000..00020000004fffff [200]
> pci 0000:02:00.3: can't claim BAR 0 [mem 0x2000000400000-0x20000004fffff]: no compatible bridge window
> PCI: Claiming 0000:02:00.3: Resource 3: 000200000010c000..000200000010ffff [200]
> pci 0000:02:00.3: can't claim BAR 3 [mem 0x200000010c000-0x200000010ffff]: no compatible bridge window
> 
> The bridge 00:02.0 resource does not get reserved as Video RAM take the position early,
> and following children resources reservation all fail.
> 
> Move down Video RAM area reservation after pci mmio get reserved,
> so we leave pci driver to use those regions.

I think this patch contains two changes:

  1) Factor pci_register_region() out of pci_register_legacy_regions()
  and do the correct bus-to-resource conversion, and

  2) Call pci_register_legacy_regions() from pci_scan_one_pbm() after
  scanning the bus instead of from pci_determine_mem_io_space()
  before.

Can you split this into two patches, one for each change?

pci_register_legacy_regions() reserves these bus address regions:

  [0xa0000-0xbffff] Video RAM
  [0xc0000-0xc7fff] Video ROM
  [0xf0000-0xfffff] System ROM

>From a PCI point of view, address space usage is normally reported by
BARs, and we register legacy regions to account for address space
that's not reported by a BAR.

For a legacy VGA device, I think that's only [0xa0000-0xbffff] (plus
some I/O ports).  I don't think a PCI device should ever use the ROM
regions mentioned above unless it has a BAR programmed to those
addresses, so I'm not sure we need to reserve them as PCI "legacy"
regions.

I suspect those ROM areas might have been copied from x86 BIOS stuff
and might not be applicable on sparc.  If you want to reserve them to
preserve the previous behavior, that's OK, but maybe we could do it
with a separate "sparc_register_legacy_regions()" or something?

I'm thinking that the VGA part of this is not really arch-specific, so
we could someday factor that out into the PCI core so you wouldn't
have to do that part in the sparc code, and splitting out the non-PCI
stuff would make that easier.

I guess we reserve the VGA RAM either for a VGA device already in the
system or to reserve space for one that might be hotplugged later.  In
your example above, there's a non-VGA device using that area, so I
suppose this patch means the 02:00.0 BAR 0 reservation works
correctly, but the subsequent VGA reservation complains about a
conflict with 02:00.0?  That "address conflict" message isn't really
accurate: there's no actual conflict because there's no VGA device.
The failure just means we won't be able to hot-add a VGA device later,
right?

> -v5: merge simplify one and use pcibios_bus_to_resource()
> 
> -v6: use pci_find_bus_resource()
> 
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
> Cc: sparclinux@vger.kernel.org
> ---
>  arch/sparc/kernel/pci.c        |  1 +
>  arch/sparc/kernel/pci_common.c | 59 ++++++++++++++++++++++--------------------
>  arch/sparc/kernel/pci_impl.h   |  1 +
>  3 files changed, 33 insertions(+), 28 deletions(-)
> 
> diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
> index c5cf813..adb9653 100644
> --- a/arch/sparc/kernel/pci.c
> +++ b/arch/sparc/kernel/pci.c
> @@ -686,6 +686,7 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
>  	pci_bus_register_of_sysfs(bus);
>  
>  	pci_claim_bus_resources(bus);
> +	pci_register_legacy_regions(bus);
>  	pci_bus_add_devices(bus);
>  	return bus;
>  }
> diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c
> index 76998f8..1ebc7ff 100644
> --- a/arch/sparc/kernel/pci_common.c
> +++ b/arch/sparc/kernel/pci_common.c
> @@ -328,41 +328,46 @@ void pci_get_pbm_props(struct pci_pbm_info *pbm)
>  	}
>  }
>  
> -static void pci_register_legacy_regions(struct resource *io_res,
> -					struct resource *mem_res)
> +static void pci_register_region(struct pci_bus *bus, const char *name,
> +				resource_size_t rstart, resource_size_t size)
>  {
> -	struct resource *p;
> +	struct resource *res, *conflict, *bus_res;
> +	struct pci_bus_region region;
>  
> -	/* VGA Video RAM. */
> -	p = kzalloc(sizeof(*p), GFP_KERNEL);
> -	if (!p)
> +	res = kzalloc(sizeof(*res), GFP_KERNEL);
> +	if (!res)
>  		return;
>  
> -	p->name = "Video RAM area";
> -	p->start = mem_res->start + 0xa0000UL;
> -	p->end = p->start + 0x1ffffUL;
> -	p->flags = IORESOURCE_BUSY;
> -	request_resource(mem_res, p);
> +	res->flags = IORESOURCE_MEM;
>  
> -	p = kzalloc(sizeof(*p), GFP_KERNEL);
> -	if (!p)
> +	region.start = rstart;
> +	region.end = rstart + size - 1UL;
> +	pcibios_bus_to_resource(bus, res, &region);
> +	bus_res = pci_find_bus_resource(bus, res);
> +	if (!bus_res) {
> +		kfree(res);
>  		return;
> +	}
> +
> +	res->name = name;
> +	res->flags |= IORESOURCE_BUSY;
> +	conflict = request_resource_conflict(bus_res, res);
> +	if (conflict) {
> +		dev_printk(KERN_DEBUG, &bus->dev,
> +			" can't claim %s %pR: address conflict with %s %pR\n",
> +			res->name, res, conflict->name, conflict);
> +		kfree(res);
> +	}
> +}
>  
> -	p->name = "System ROM";
> -	p->start = mem_res->start + 0xf0000UL;
> -	p->end = p->start + 0xffffUL;
> -	p->flags = IORESOURCE_BUSY;
> -	request_resource(mem_res, p);
> +void pci_register_legacy_regions(struct pci_bus *bus)
> +{
> +	/* VGA Video RAM. */
> +	pci_register_region(bus, "Video RAM area", 0xa0000UL, 0x20000UL);
>  
> -	p = kzalloc(sizeof(*p), GFP_KERNEL);
> -	if (!p)
> -		return;
> +	pci_register_region(bus, "System ROM",     0xf0000UL, 0x10000UL);
>  
> -	p->name = "Video ROM";
> -	p->start = mem_res->start + 0xc0000UL;
> -	p->end = p->start + 0x7fffUL;
> -	p->flags = IORESOURCE_BUSY;
> -	request_resource(mem_res, p);
> +	pci_register_region(bus, "Video ROM",      0xc0000UL,  0x8000UL);
>  }
>  
>  static void pci_register_iommu_region(struct pci_pbm_info *pbm)
> @@ -504,8 +509,6 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
>  	if (pbm->mem64_space.flags)
>  		request_resource(&iomem_resource, &pbm->mem64_space);
>  
> -	pci_register_legacy_regions(&pbm->io_space,
> -				    &pbm->mem_space);
>  	pci_register_iommu_region(pbm);
>  }
>  
> diff --git a/arch/sparc/kernel/pci_impl.h b/arch/sparc/kernel/pci_impl.h
> index 2853af7..ff8f5e1 100644
> --- a/arch/sparc/kernel/pci_impl.h
> +++ b/arch/sparc/kernel/pci_impl.h
> @@ -167,6 +167,7 @@ void pci_get_pbm_props(struct pci_pbm_info *pbm);
>  struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
>  				 struct device *parent);
>  void pci_determine_mem_io_space(struct pci_pbm_info *pbm);
> +void pci_register_legacy_regions(struct pci_bus *bus);
>  
>  /* Error reporting support. */
>  void pci_scan_for_target_abort(struct pci_pbm_info *, struct pci_bus *);
> -- 
> 2.9.3
> 

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

* Re: [PATCH 03/13] sparc/PCI: Reserve legacy mmio after PCI mmio
@ 2017-05-03 22:03     ` Bjorn Helgaas
  0 siblings, 0 replies; 33+ messages in thread
From: Bjorn Helgaas @ 2017-05-03 22:03 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt, Wei Yang,
	Khalid Aziz, linux-pci, linux-kernel, sparclinux

On Thu, Apr 20, 2017 at 10:04:50PM -0700, Yinghai Lu wrote:
> On one system found bunch of claim resource fail from pci device.
> pci_sun4v f02b894c: PCI host bridge to bus 0000:00
> pci_bus 0000:00: root bus resource [io  0x2007e00000000-0x2007e0fffffff] (bus address [0x0000-0xfffffff])
> pci_bus 0000:00: root bus resource [mem 0x2000000000000-0x200007effffff] (bus address [0x00000000-0x7effffff])
> pci_bus 0000:00: root bus resource [mem 0x2000100000000-0x20007ffffffff] (bus address [0x100000000-0x7ffffffff])
> ...
> PCI: Claiming 0000:00:02.0: Resource 14: 0002000000000000..00020000004fffff [200]
> pci 0000:00:02.0: can't claim BAR 14 [mem 0x2000000000000-0x20000004fffff]: address conflict with Video RAM area [??? 0x20000000a0000-0x20000000bffff flags 0x80000000]
> pci 0000:02:00.0: can't claim BAR 0 [mem 0x2000000000000-0x20000000fffff]: no compatible bridge window
> PCI: Claiming 0000:02:00.0: Resource 3: 0002000000100000..0002000000103fff [200]
> pci 0000:02:00.0: can't claim BAR 3 [mem 0x2000000100000-0x2000000103fff]: no compatible bridge window
> PCI: Claiming 0000:02:00.1: Resource 0: 0002000000200000..00020000002fffff [200]
> pci 0000:02:00.1: can't claim BAR 0 [mem 0x2000000200000-0x20000002fffff]: no compatible bridge window
> PCI: Claiming 0000:02:00.1: Resource 3: 0002000000104000..0002000000107fff [200]
> pci 0000:02:00.1: can't claim BAR 3 [mem 0x2000000104000-0x2000000107fff]: no compatible bridge window
> PCI: Claiming 0000:02:00.2: Resource 0: 0002000000300000..00020000003fffff [200]
> pci 0000:02:00.2: can't claim BAR 0 [mem 0x2000000300000-0x20000003fffff]: no compatible bridge window
> PCI: Claiming 0000:02:00.2: Resource 3: 0002000000108000..000200000010bfff [200]
> pci 0000:02:00.2: can't claim BAR 3 [mem 0x2000000108000-0x200000010bfff]: no compatible bridge window
> PCI: Claiming 0000:02:00.3: Resource 0: 0002000000400000..00020000004fffff [200]
> pci 0000:02:00.3: can't claim BAR 0 [mem 0x2000000400000-0x20000004fffff]: no compatible bridge window
> PCI: Claiming 0000:02:00.3: Resource 3: 000200000010c000..000200000010ffff [200]
> pci 0000:02:00.3: can't claim BAR 3 [mem 0x200000010c000-0x200000010ffff]: no compatible bridge window
> 
> The bridge 00:02.0 resource does not get reserved as Video RAM take the position early,
> and following children resources reservation all fail.
> 
> Move down Video RAM area reservation after pci mmio get reserved,
> so we leave pci driver to use those regions.

I think this patch contains two changes:

  1) Factor pci_register_region() out of pci_register_legacy_regions()
  and do the correct bus-to-resource conversion, and

  2) Call pci_register_legacy_regions() from pci_scan_one_pbm() after
  scanning the bus instead of from pci_determine_mem_io_space()
  before.

Can you split this into two patches, one for each change?

pci_register_legacy_regions() reserves these bus address regions:

  [0xa0000-0xbffff] Video RAM
  [0xc0000-0xc7fff] Video ROM
  [0xf0000-0xfffff] System ROM

From a PCI point of view, address space usage is normally reported by
BARs, and we register legacy regions to account for address space
that's not reported by a BAR.

For a legacy VGA device, I think that's only [0xa0000-0xbffff] (plus
some I/O ports).  I don't think a PCI device should ever use the ROM
regions mentioned above unless it has a BAR programmed to those
addresses, so I'm not sure we need to reserve them as PCI "legacy"
regions.

I suspect those ROM areas might have been copied from x86 BIOS stuff
and might not be applicable on sparc.  If you want to reserve them to
preserve the previous behavior, that's OK, but maybe we could do it
with a separate "sparc_register_legacy_regions()" or something?

I'm thinking that the VGA part of this is not really arch-specific, so
we could someday factor that out into the PCI core so you wouldn't
have to do that part in the sparc code, and splitting out the non-PCI
stuff would make that easier.

I guess we reserve the VGA RAM either for a VGA device already in the
system or to reserve space for one that might be hotplugged later.  In
your example above, there's a non-VGA device using that area, so I
suppose this patch means the 02:00.0 BAR 0 reservation works
correctly, but the subsequent VGA reservation complains about a
conflict with 02:00.0?  That "address conflict" message isn't really
accurate: there's no actual conflict because there's no VGA device.
The failure just means we won't be able to hot-add a VGA device later,
right?

> -v5: merge simplify one and use pcibios_bus_to_resource()
> 
> -v6: use pci_find_bus_resource()
> 
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
> Cc: sparclinux@vger.kernel.org
> ---
>  arch/sparc/kernel/pci.c        |  1 +
>  arch/sparc/kernel/pci_common.c | 59 ++++++++++++++++++++++--------------------
>  arch/sparc/kernel/pci_impl.h   |  1 +
>  3 files changed, 33 insertions(+), 28 deletions(-)
> 
> diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
> index c5cf813..adb9653 100644
> --- a/arch/sparc/kernel/pci.c
> +++ b/arch/sparc/kernel/pci.c
> @@ -686,6 +686,7 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
>  	pci_bus_register_of_sysfs(bus);
>  
>  	pci_claim_bus_resources(bus);
> +	pci_register_legacy_regions(bus);
>  	pci_bus_add_devices(bus);
>  	return bus;
>  }
> diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c
> index 76998f8..1ebc7ff 100644
> --- a/arch/sparc/kernel/pci_common.c
> +++ b/arch/sparc/kernel/pci_common.c
> @@ -328,41 +328,46 @@ void pci_get_pbm_props(struct pci_pbm_info *pbm)
>  	}
>  }
>  
> -static void pci_register_legacy_regions(struct resource *io_res,
> -					struct resource *mem_res)
> +static void pci_register_region(struct pci_bus *bus, const char *name,
> +				resource_size_t rstart, resource_size_t size)
>  {
> -	struct resource *p;
> +	struct resource *res, *conflict, *bus_res;
> +	struct pci_bus_region region;
>  
> -	/* VGA Video RAM. */
> -	p = kzalloc(sizeof(*p), GFP_KERNEL);
> -	if (!p)
> +	res = kzalloc(sizeof(*res), GFP_KERNEL);
> +	if (!res)
>  		return;
>  
> -	p->name = "Video RAM area";
> -	p->start = mem_res->start + 0xa0000UL;
> -	p->end = p->start + 0x1ffffUL;
> -	p->flags = IORESOURCE_BUSY;
> -	request_resource(mem_res, p);
> +	res->flags = IORESOURCE_MEM;
>  
> -	p = kzalloc(sizeof(*p), GFP_KERNEL);
> -	if (!p)
> +	region.start = rstart;
> +	region.end = rstart + size - 1UL;
> +	pcibios_bus_to_resource(bus, res, &region);
> +	bus_res = pci_find_bus_resource(bus, res);
> +	if (!bus_res) {
> +		kfree(res);
>  		return;
> +	}
> +
> +	res->name = name;
> +	res->flags |= IORESOURCE_BUSY;
> +	conflict = request_resource_conflict(bus_res, res);
> +	if (conflict) {
> +		dev_printk(KERN_DEBUG, &bus->dev,
> +			" can't claim %s %pR: address conflict with %s %pR\n",
> +			res->name, res, conflict->name, conflict);
> +		kfree(res);
> +	}
> +}
>  
> -	p->name = "System ROM";
> -	p->start = mem_res->start + 0xf0000UL;
> -	p->end = p->start + 0xffffUL;
> -	p->flags = IORESOURCE_BUSY;
> -	request_resource(mem_res, p);
> +void pci_register_legacy_regions(struct pci_bus *bus)
> +{
> +	/* VGA Video RAM. */
> +	pci_register_region(bus, "Video RAM area", 0xa0000UL, 0x20000UL);
>  
> -	p = kzalloc(sizeof(*p), GFP_KERNEL);
> -	if (!p)
> -		return;
> +	pci_register_region(bus, "System ROM",     0xf0000UL, 0x10000UL);
>  
> -	p->name = "Video ROM";
> -	p->start = mem_res->start + 0xc0000UL;
> -	p->end = p->start + 0x7fffUL;
> -	p->flags = IORESOURCE_BUSY;
> -	request_resource(mem_res, p);
> +	pci_register_region(bus, "Video ROM",      0xc0000UL,  0x8000UL);
>  }
>  
>  static void pci_register_iommu_region(struct pci_pbm_info *pbm)
> @@ -504,8 +509,6 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
>  	if (pbm->mem64_space.flags)
>  		request_resource(&iomem_resource, &pbm->mem64_space);
>  
> -	pci_register_legacy_regions(&pbm->io_space,
> -				    &pbm->mem_space);
>  	pci_register_iommu_region(pbm);
>  }
>  
> diff --git a/arch/sparc/kernel/pci_impl.h b/arch/sparc/kernel/pci_impl.h
> index 2853af7..ff8f5e1 100644
> --- a/arch/sparc/kernel/pci_impl.h
> +++ b/arch/sparc/kernel/pci_impl.h
> @@ -167,6 +167,7 @@ void pci_get_pbm_props(struct pci_pbm_info *pbm);
>  struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
>  				 struct device *parent);
>  void pci_determine_mem_io_space(struct pci_pbm_info *pbm);
> +void pci_register_legacy_regions(struct pci_bus *bus);
>  
>  /* Error reporting support. */
>  void pci_scan_for_target_abort(struct pci_pbm_info *, struct pci_bus *);
> -- 
> 2.9.3
> 

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

* Re: [PATCH 09/13] PCI: Check pref compatible bit for mem64 resource of PCIe device
  2017-04-21  5:04   ` Yinghai Lu
@ 2017-05-04 21:19     ` Bjorn Helgaas
  -1 siblings, 0 replies; 33+ messages in thread
From: Bjorn Helgaas @ 2017-05-04 21:19 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt, Wei Yang,
	Khalid Aziz, linux-pci, linux-kernel, sparclinux

On Thu, Apr 20, 2017 at 10:04:56PM -0700, Yinghai Lu wrote:
> We still get "no compatible bridge window" warning on sparc T5-8
> after we add support for 64bit resource parsing for root bus.
> 
>  PCI: scan_bus[/pci@300/pci@1/pci@0/pci@6] bus no 8
>  PCI: Claiming 0000:00:01.0: Resource 15: 0000800100000000..00008004afffffff [220c]
>  PCI: Claiming 0000:01:00.0: Resource 15: 0000800100000000..00008004afffffff [220c]
>  PCI: Claiming 0000:02:04.0: Resource 15: 0000800100000000..000080012fffffff [220c]
>  PCI: Claiming 0000:03:00.0: Resource 15: 0000800100000000..000080012fffffff [220c]
>  PCI: Claiming 0000:04:06.0: Resource 14: 0000800100000000..000080010fffffff [220c]
>  PCI: Claiming 0000:05:00.0: Resource 0: 0000800100000000..0000800100001fff [204]
>  pci 0000:05:00.0: can't claim BAR 0 [mem 0x800100000000-0x800100001fff]: no compatible bridge window
> 
> All the bridges 64-bit resource have pref bit, but the device resource does not
> have pref set, then we can not find parent for the device resource,
> as we can not put non-pref mmio under pref mmio.
> 
> According to pcie spec errta
> https://www.pcisig.com/specifications/pciexpress/base2/PCIe_Base_r2.1_Errata_08Jun10.pdf
> page 13, in some case it is ok to mark some as pref.

This link is broken.  The text is included as an implementation note
in the PCIe r3.1 spec, sec 7.5.2.1.  If you cite that, I don't think
we need the link.  Please also fix the broken link in the patch below.

This changelog needs to recap the conditions in that implementation
note, i.e., entire path is PCIe, no conventional PCI or PCI-X devices
perform peer-to-peer, no byte merging, etc.  And we need something
about why we believe these conditions all hold.

In particular, I'm a little concerned about the peer-to-peer question
and the TH bit.  There are peer-to-peer patches being discussed,
though I don't know whether they include conventional PCI and PCI-X.

I don't think Linux currently does anything with the TH bit, but if we
do in the future, or if BIOS enabled TH via the TPH Requester
Capability (PCIe r3.1, sec 7.26) it seems like we could break
something.  Maybe we need to check for TPH being enabled?  I'm
interested in your opinion here.  The changelog should show that
you've considered the issue.

If we support peer-to-peer, I guess that if we do put a
non-prefetchable BAR in a prefetchable window, we would have to
prevent any device in the hierarchy from enabling TPH?

I have no idea how we know whether the BAR could be a target of a
speculative Memory Read.  I guess maybe the CPU ioremap properties are
such that speculative reads are prohibited for MMIO apertures?  Maybe
you could investigate that and include the results?

> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 5548044..676b55f 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -1920,6 +1920,36 @@ static void pci_dma_configure(struct pci_dev *dev)
>  	pci_put_host_bridge_device(bridge);
>  }
>  
> +static bool pci_up_path_over_pcie(struct pci_bus *bus)
> +{
> +	if (pci_is_root_bus(bus))
> +		return true;
> +
> +	if (bus->self && !pci_is_pcie(bus->self))
> +		return false;
> +
> +	return pci_up_path_over_pcie(bus->parent);
> +}
> +
> +/*
> + * According to
> + * https://www.pcisig.com/specifications/pciexpress/base2/PCIe_Base_r2.1_Errata_08Jun10.pdf
> + * page 13, system firmware could put some 64bit non-pref under 64bit pref,
> + * on some cases.
> + * Let's mark if entire path from the host to the adapter is over PCI
> + * Express. later will use that compute pref compaitable bit.
> + */
> +static void pci_set_on_all_pcie_path(struct pci_dev *dev)
> +{
> +	if (!pci_is_pcie(dev))
> +		return;
> +
> +	if (!pci_up_path_over_pcie(dev->bus))
> +		return;
> +
> +	dev->on_all_pcie_path = 1;

I think this can be set more simply as:

  if (pci_is_pcie(dev)) {
    if (pci_is_root_bus(dev->bus))
      dev->pcie_path = 1;
    else if (dev->bus->self && dev->bus->self->pcie_path)
      dev->pcie_path = 1;
  }

How about if you just put this code in set_pcie_port_type() so you
don't have to add another function and worry about whether it's called
after pcie_cap is assigned?  Then you wouldn't need the pci_is_pcie()
test either.

> +}
> +
>  void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
>  {
>  	int ret;
> @@ -1950,6 +1980,9 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
>  	/* Initialize various capabilities */
>  	pci_init_capabilities(dev);
>  
> +	/* After pcie_cap is assigned */
> +	pci_set_on_all_pcie_path(dev);
> +
>  	/*
>  	 * Add the device to our list of discovered devices
>  	 * and the bus list for fixup functions, etc.

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

* Re: [PATCH 09/13] PCI: Check pref compatible bit for mem64 resource of PCIe device
@ 2017-05-04 21:19     ` Bjorn Helgaas
  0 siblings, 0 replies; 33+ messages in thread
From: Bjorn Helgaas @ 2017-05-04 21:19 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt, Wei Yang,
	Khalid Aziz, linux-pci, linux-kernel, sparclinux

On Thu, Apr 20, 2017 at 10:04:56PM -0700, Yinghai Lu wrote:
> We still get "no compatible bridge window" warning on sparc T5-8
> after we add support for 64bit resource parsing for root bus.
> 
>  PCI: scan_bus[/pci@300/pci@1/pci@0/pci@6] bus no 8
>  PCI: Claiming 0000:00:01.0: Resource 15: 0000800100000000..00008004afffffff [220c]
>  PCI: Claiming 0000:01:00.0: Resource 15: 0000800100000000..00008004afffffff [220c]
>  PCI: Claiming 0000:02:04.0: Resource 15: 0000800100000000..000080012fffffff [220c]
>  PCI: Claiming 0000:03:00.0: Resource 15: 0000800100000000..000080012fffffff [220c]
>  PCI: Claiming 0000:04:06.0: Resource 14: 0000800100000000..000080010fffffff [220c]
>  PCI: Claiming 0000:05:00.0: Resource 0: 0000800100000000..0000800100001fff [204]
>  pci 0000:05:00.0: can't claim BAR 0 [mem 0x800100000000-0x800100001fff]: no compatible bridge window
> 
> All the bridges 64-bit resource have pref bit, but the device resource does not
> have pref set, then we can not find parent for the device resource,
> as we can not put non-pref mmio under pref mmio.
> 
> According to pcie spec errta
> https://www.pcisig.com/specifications/pciexpress/base2/PCIe_Base_r2.1_Errata_08Jun10.pdf
> page 13, in some case it is ok to mark some as pref.

This link is broken.  The text is included as an implementation note
in the PCIe r3.1 spec, sec 7.5.2.1.  If you cite that, I don't think
we need the link.  Please also fix the broken link in the patch below.

This changelog needs to recap the conditions in that implementation
note, i.e., entire path is PCIe, no conventional PCI or PCI-X devices
perform peer-to-peer, no byte merging, etc.  And we need something
about why we believe these conditions all hold.

In particular, I'm a little concerned about the peer-to-peer question
and the TH bit.  There are peer-to-peer patches being discussed,
though I don't know whether they include conventional PCI and PCI-X.

I don't think Linux currently does anything with the TH bit, but if we
do in the future, or if BIOS enabled TH via the TPH Requester
Capability (PCIe r3.1, sec 7.26) it seems like we could break
something.  Maybe we need to check for TPH being enabled?  I'm
interested in your opinion here.  The changelog should show that
you've considered the issue.

If we support peer-to-peer, I guess that if we do put a
non-prefetchable BAR in a prefetchable window, we would have to
prevent any device in the hierarchy from enabling TPH?

I have no idea how we know whether the BAR could be a target of a
speculative Memory Read.  I guess maybe the CPU ioremap properties are
such that speculative reads are prohibited for MMIO apertures?  Maybe
you could investigate that and include the results?

> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 5548044..676b55f 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -1920,6 +1920,36 @@ static void pci_dma_configure(struct pci_dev *dev)
>  	pci_put_host_bridge_device(bridge);
>  }
>  
> +static bool pci_up_path_over_pcie(struct pci_bus *bus)
> +{
> +	if (pci_is_root_bus(bus))
> +		return true;
> +
> +	if (bus->self && !pci_is_pcie(bus->self))
> +		return false;
> +
> +	return pci_up_path_over_pcie(bus->parent);
> +}
> +
> +/*
> + * According to
> + * https://www.pcisig.com/specifications/pciexpress/base2/PCIe_Base_r2.1_Errata_08Jun10.pdf
> + * page 13, system firmware could put some 64bit non-pref under 64bit pref,
> + * on some cases.
> + * Let's mark if entire path from the host to the adapter is over PCI
> + * Express. later will use that compute pref compaitable bit.
> + */
> +static void pci_set_on_all_pcie_path(struct pci_dev *dev)
> +{
> +	if (!pci_is_pcie(dev))
> +		return;
> +
> +	if (!pci_up_path_over_pcie(dev->bus))
> +		return;
> +
> +	dev->on_all_pcie_path = 1;

I think this can be set more simply as:

  if (pci_is_pcie(dev)) {
    if (pci_is_root_bus(dev->bus))
      dev->pcie_path = 1;
    else if (dev->bus->self && dev->bus->self->pcie_path)
      dev->pcie_path = 1;
  }

How about if you just put this code in set_pcie_port_type() so you
don't have to add another function and worry about whether it's called
after pcie_cap is assigned?  Then you wouldn't need the pci_is_pcie()
test either.

> +}
> +
>  void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
>  {
>  	int ret;
> @@ -1950,6 +1980,9 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
>  	/* Initialize various capabilities */
>  	pci_init_capabilities(dev);
>  
> +	/* After pcie_cap is assigned */
> +	pci_set_on_all_pcie_path(dev);
> +
>  	/*
>  	 * Add the device to our list of discovered devices
>  	 * and the bus list for fixup functions, etc.

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

* Re: [PATCH 10/13] PCI: Only treat non-pref mmio64 as pref if all bridges have MEM_64
  2017-04-21  5:04 ` [PATCH 10/13] PCI: Only treat non-pref mmio64 as pref if all bridges have MEM_64 Yinghai Lu
@ 2017-05-04 21:43   ` Bjorn Helgaas
  0 siblings, 0 replies; 33+ messages in thread
From: Bjorn Helgaas @ 2017-05-04 21:43 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt, Wei Yang,
	Khalid Aziz, linux-pci, linux-kernel

On Thu, Apr 20, 2017 at 10:04:57PM -0700, Yinghai Lu wrote:
> If any bridge up to root only have 32bit pref mmio, We don't need to
> treat device non-pref mmio64 as as pref mmio64.

I don't understand the reasoning here.  

Apparently it is only safe to put a non-prefetchable PCIe BAR in a
prefetchable window if all upstream bridges have a 64-bit prefetchable
window?  Why is that?  Why is it important that the prefetchable
window be 64-bit?  I don't see this mentioned in the implementation
note.

Does this mean "PCI: Check pref compatible bit for mem64 resource of
PCIe device" can make unsafe assignments until we apply this patch?
If so, I don't want that sort of bisection hole.

What bad thing happens without this patch?

> We need to move pci_bridge_check_ranges calling early.
> For parent bridges pref mmio BAR may not allocated by BIOS, res flags
> is still 0, we need to have it correct set before we check them for
> child device resources.
> 
> -v2: check all bus resources instead of just res[15].
> 
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
> ---
>  drivers/pci/setup-bus.c | 31 +++++++++++++++++++++++++++++--
>  1 file changed, 29 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
> index 3de66e6..b3fd314 100644
> --- a/drivers/pci/setup-bus.c
> +++ b/drivers/pci/setup-bus.c
> @@ -735,6 +735,29 @@ int pci_claim_bridge_resource(struct pci_dev *bridge, int i)
>  	return -EINVAL;
>  }
>  
> +static bool pci_up_path_over_pref_mem64(struct pci_bus *bus)
> +{
> +	if (pci_is_root_bus(bus))
> +		return true;
> +
> +	if (bus->self) {
> +		int i;
> +		bool found = false;
> +		struct resource *res;
> +
> +		pci_bus_for_each_resource(bus, res, i)
> +			if (res->flags & IORESOURCE_MEM_64) {
> +				found = true;
> +				break;
> +			}
> +
> +		if (!found)
> +			return false;
> +	}
> +
> +	return pci_up_path_over_pref_mem64(bus->parent);
> +}
> +
>  int pci_resource_pref_compatible(const struct pci_dev *dev,
>  				 struct resource *res)
>  {
> @@ -743,7 +766,8 @@ int pci_resource_pref_compatible(const struct pci_dev *dev,
>  
>  	if ((res->flags & IORESOURCE_MEM) &&
>  	    (res->flags & IORESOURCE_MEM_64) &&
> -	    dev->on_all_pcie_path)
> +	    dev->on_all_pcie_path &&
> +	    pci_up_path_over_pref_mem64(dev->bus))
>  		return res->flags | IORESOURCE_PREFETCH;
>  
>  	return res->flags;
> @@ -1236,6 +1260,10 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head)
>  	struct resource *b_res;
>  	int ret;
>  
> +	if (!pci_is_root_bus(bus) &&
> +	    (bus->self->class >> 8) == PCI_CLASS_BRIDGE_PCI)
> +		pci_bridge_check_ranges(bus);
> +
>  	list_for_each_entry(dev, &bus->devices, bus_list) {
>  		struct pci_bus *b = dev->subordinate;
>  		if (!b)
> @@ -1263,7 +1291,6 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head)
>  		break;
>  
>  	case PCI_CLASS_BRIDGE_PCI:
> -		pci_bridge_check_ranges(bus);
>  		if (bus->self->is_hotplug_bridge) {
>  			additional_io_size  = pci_hotplug_io_size;
>  			additional_mem_size = pci_hotplug_mem_size;
> -- 
> 2.9.3
> 

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

* Re: [PATCH 11/13] PCI: Add has_mem64 for struct host_bridge
  2017-04-21  5:04 ` [PATCH 11/13] PCI: Add has_mem64 for struct host_bridge Yinghai Lu
@ 2017-05-04 23:04   ` Bjorn Helgaas
  2017-05-08  8:54     ` Christian König
  0 siblings, 1 reply; 33+ messages in thread
From: Bjorn Helgaas @ 2017-05-04 23:04 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt, Wei Yang,
	Khalid Aziz, linux-pci, linux-kernel, Christian König

[+cc Christian]

On Thu, Apr 20, 2017 at 10:04:58PM -0700, Yinghai Lu wrote:
> Add has_mem64 for struct host_bridge, on root bus that does not support
> mmio64 above 4g, will not set that.
> 
> We will use that info next two following patches:
> 1. Don't treat non-pref mmio64 as pref mmio, so will not put
>    it under bridge's pref range when rescan the devices
> 2. will keep pref mmio64 and pref mmio32 under bridge pref bar.
> 
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
> ---
>  drivers/pci/probe.c | 7 +++++++
>  include/linux/pci.h | 1 +
>  2 files changed, 8 insertions(+)
> 
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 676b55f..8f439e0 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -818,6 +818,13 @@ int pci_register_host_bridge(struct pci_host_bridge *bridge)
>  			addr[0] = '\0';
>  
>  		dev_info(&bus->dev, "root bus resource %pR%s\n", res, addr);
> +
> +		if (resource_type(res) == IORESOURCE_MEM) {
> +			if ((res->end - offset) > 0xffffffff)
> +				bridge->has_mem64 = 1;

This part makes sense -- if any part of the window extends above 4G,
only a 64-bit BAR can use the part above 4G.

> +			if ((res->start - offset) > 0xffffffff)
> +				res->flags |= IORESOURCE_MEM_64;

But I don't understand this part.  You only set IORESOURCE_MEM_64 if
the *start* is above 4G?  If the window started at 2GB and ended at
6GB, you wouldn't set IORESOURCE_MEM_64?

And I don't understand where this IORESOURCE_MEM_64 in res->flags is
used.  It seems like the only possible place is this test added by the
last patch:

  int pci_bus_alloc_resource(bus, res, ...)
  {
    if (res->flags & mmio64) {

but this patch is setting IORESOURCE_MEM_64 in the host bridge window,
i.e., the bus resource, and pci_bus_alloc_resource() is testing the
flags of the resource we're allocating *from* the bus resource.

> +		}

I *think* this will be broken by the current implementation of
Christian's patch to enable a 64-bit host bridge window:

  https://lkml.kernel.org/r/1493890270-1188-5-git-send-email-deathsimple@vodafone.de

because pci_register_host_bridge() runs before we scan the bus, and
Christian's patch adds a quirk that runs when we enumerate the AMD
host bridge device.

If we apply this and Christian's patch, I think we could end up with
a host bridge window above 4G, but with bridge->has_mem64 not set.

>  	}
>  
>  	down_write(&pci_bus_sem);
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index b14dd94..a3693ef 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -436,6 +436,7 @@ struct pci_host_bridge {
>  	void *release_data;
>  	struct msi_controller *msi;
>  	unsigned int ignore_reset_delay:1;	/* for entire hierarchy */
> +	unsigned int has_mem64:1;
>  	/* Resource alignment requirements */
>  	resource_size_t (*align_resource)(struct pci_dev *dev,
>  			const struct resource *res,
> -- 
> 2.9.3
> 

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

* Re: [PATCH 13/13] PCI: Restore pref MMIO allocation logic for host bridge without mmio64
  2017-04-21  5:05 ` [PATCH 13/13] PCI: Restore pref MMIO allocation logic for host bridge without mmio64 Yinghai Lu
@ 2017-05-05  1:24   ` Bjorn Helgaas
  0 siblings, 0 replies; 33+ messages in thread
From: Bjorn Helgaas @ 2017-05-05  1:24 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt, Wei Yang,
	Khalid Aziz, linux-pci, linux-kernel

On Thu, Apr 20, 2017 at 10:05:00PM -0700, Yinghai Lu wrote:
> From 5b2854155 (PCI: Restrict 64-bit prefetchable bridge windows to 64-bit
> resources), we change the logic for pref mmio allocation:
> When bridge pref support mmio64, we will only put children pref
> that support mmio64 into it, and will put children pref mmio32
> into bridge's non-pref mmio32.
> 
> That could leave bridge pref bar not used when that pref bar is mmio64,
> and children res only has mmio32.
> Also could have allocation failure when non-pref mmio32 is not big
> enough space for those children pref mmio32.
> 
> That is not rational when the host bridge does not have 64bit mmio
> above 4g at all.
> 
> The patch restore to old logic:
> when host bridge does not have has_mem64, put children pref mmio64 and
> pref mmio32 all under bridges pref bars.
> 
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
> ---
>  drivers/pci/bus.c       |  4 +++-
>  drivers/pci/setup-bus.c | 13 +++++++++----
>  drivers/pci/setup-res.c |  9 ++++++---
>  3 files changed, 18 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
> index bc56cf1..79205fb 100644
> --- a/drivers/pci/bus.c
> +++ b/drivers/pci/bus.c
> @@ -233,8 +233,10 @@ int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
>  {
>  #ifdef CONFIG_PCI_BUS_ADDR_T_64BIT
>  	int rc;
> +	unsigned long mmio64 = pci_find_host_bridge(bus)->has_mem64 ?
> +				IORESOURCE_MEM_64 : 0;
>  
> -	if (res->flags & IORESOURCE_MEM_64) {
> +	if (res->flags & mmio64) {
>  		rc = pci_bus_alloc_from_region(bus, res, size, align, min,
>  					       type_mask, alignf, alignf_data,
>  					       &pci_high);

Why do we need this change?  This only makes a difference when
mmio64==0, i.e., when the host bridge has no windows above 4GB.
In that case, allocating from pci_high (0x100000000-0xffffffffffffffff)
should fail anyway because there are no windows up there.

When that fails, we'll try to allocate from pci_64_bit, which is the
entire 64 bit address region, which should still be OK.

> diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
> index 7a0e59b..f29cf5d 100644
> --- a/drivers/pci/setup-bus.c
> +++ b/drivers/pci/setup-bus.c
> @@ -1308,7 +1308,8 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head)
>  		b_res = &bus->self->resource[PCI_BRIDGE_RESOURCES];
>  		mask = IORESOURCE_MEM;
>  		prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH;
> -		if (b_res[2].flags & IORESOURCE_MEM_64) {
> +		if ((b_res[2].flags & IORESOURCE_MEM_64) &&
> +		    pci_find_host_bridge(bus)->has_mem64) {
>  			prefmask |= IORESOURCE_MEM_64;
>  			ret = pbus_size_mem(bus, prefmask, prefmask,
>  				  prefmask, prefmask,
> @@ -1578,17 +1579,21 @@ static void pci_bridge_release_resources(struct pci_bus *bus,
>  	 *	  io port.
>  	 *     2. if there is non pref mmio assign fail, release bridge
>  	 *	  nonpref mmio.
> -	 *     3. if there is 64bit pref mmio assign fail, and bridge pref
> +	 *     3. if there is pref mmio assign fail, and host bridge does
> +	 *	  have 64bit mmio, release bridge pref mmio.
> +	 *     4. if there is 64bit pref mmio assign fail, and bridge pref
>  	 *	  is 64bit, release bridge pref mmio.
> -	 *     4. if there is pref mmio assign fail, and bridge pref is
> +	 *     5. if there is pref mmio assign fail, and bridge pref is
>  	 *	  32bit mmio, release bridge pref mmio
> -	 *     5. if there is pref mmio assign fail, and bridge pref is not
> +	 *     6. if there is pref mmio assign fail, and bridge pref is not
>  	 *	  assigned, release bridge nonpref mmio.
>  	 */
>  	if (type & IORESOURCE_IO)
>  		idx = 0;
>  	else if (!(type & IORESOURCE_PREFETCH))
>  		idx = 1;
> +	else if (!pci_find_host_bridge(bus)->has_mem64)
> +		idx = 2;
>  	else if ((type & IORESOURCE_MEM_64) &&
>  		 (b_res[2].flags & IORESOURCE_MEM_64))
>  		idx = 2;
> diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
> index 2aeb4bc..49cfb55 100644
> --- a/drivers/pci/setup-res.c
> +++ b/drivers/pci/setup-res.c
> @@ -240,6 +240,8 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
>  	struct resource *res = dev->resource + resno;
>  	resource_size_t min;
>  	int ret;
> +	unsigned long mmio64 = pci_find_host_bridge(bus)->has_mem64 ?
> +				IORESOURCE_MEM_64 : 0;
>  
>  	min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
>  
> @@ -251,7 +253,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
>  	 * things differently than they were sized, not everything will fit.
>  	 */
>  	ret = pci_bus_alloc_resource(bus, res, size, align, min,
> -				     IORESOURCE_PREFETCH | IORESOURCE_MEM_64,
> +				     IORESOURCE_PREFETCH | mmio64,

It's kind of frustrating when you update the code, but not the
matching comment.  The comment just above this change says:

     * First, try exact prefetching match.  Even if a 64-bit
     * prefetchable bridge window is below 4GB, we can't put a 32-bit
     * prefetchable resource in it because pbus_size_mem() assumes a
     * 64-bit window will contain no 32-bit resources.  If we assign
     * things differently than they were sized, not everything will fit.

You changed the code so we now *do* allow a 32-bit prefetchable
resource in a 64-bit prefetchable window, as long as all the host
bridge windows are below 4GB.  Please update the comment accordingly.

The comment also says that this assignment code must match what
pbus_size_mem() does, but the only change to pbus_size_mem() is in a
separate patch.  Shouldn't they be done together so they remain in
sync?

>  				     pcibios_align_resource, dev);
>  	if (ret == 0)
>  		return 0;
> @@ -260,7 +262,8 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
>  	 * If the prefetchable window is only 32 bits wide, we can put
>  	 * 64-bit prefetchable resources in it.
>  	 */
> -	if ((res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) ==
> +	if (mmio64 &&
> +	    (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) ==
>  	     (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) {
>  		ret = pci_bus_alloc_resource(bus, res, size, align, min,
>  					     IORESOURCE_PREFETCH,

Why do we need this change?  Please just update the comments to match
the code.

> @@ -275,7 +278,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
>  	 * non-prefetchable, the first call already tried the only possibility
>  	 * so we don't need to try again.
>  	 */
> -	if (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64))
> +	if (res->flags & (IORESOURCE_PREFETCH | mmio64))
>  		ret = pci_bus_alloc_resource(bus, res, size, align, min, 0,
>  					     pcibios_align_resource, dev);
>  
> -- 
> 2.9.3
> 

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

* Re: [PATCH 04/13] sparc/PCI: Add IORESOURCE_MEM_64 for 64-bit resource in OF parsing
  2017-04-21  5:04   ` Yinghai Lu
@ 2017-05-05 13:34     ` Bjorn Helgaas
  -1 siblings, 0 replies; 33+ messages in thread
From: Bjorn Helgaas @ 2017-05-05 13:34 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt, Wei Yang,
	Khalid Aziz, linux-pci, linux-kernel, sparclinux

On Thu, Apr 20, 2017 at 10:04:51PM -0700, Yinghai Lu wrote:
> For device resource with PREF bit setting under bridge 64-bit pref resource,
> we need to make sure only set PREF for 64bit resource.
> 
> so this patch set IORESOUCE_MEM_64 for 64bit resource during OF device

s/IORESOUCE_MEM_64/IORESOURCE_MEM_64/

This misspelling occurs three times in the series; please fix them all.

> resource flags parsing.
> 
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=96261
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=96241
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: sparclinux@vger.kernel.org
> Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
> ---
>  arch/sparc/kernel/of_device_32.c | 5 +++--
>  arch/sparc/kernel/of_device_64.c | 5 +++--
>  2 files changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c
> index 185aa96..3e9f273 100644
> --- a/arch/sparc/kernel/of_device_32.c
> +++ b/arch/sparc/kernel/of_device_32.c
> @@ -83,11 +83,12 @@ static unsigned long of_bus_pci_get_flags(const u32 *addr, unsigned long flags)
>  	case 0x01:
>  		flags |= IORESOURCE_IO;
>  		break;
> -
>  	case 0x02: /* 32 bits */
> -	case 0x03: /* 64 bits */
>  		flags |= IORESOURCE_MEM;
>  		break;
> +	case 0x03: /* 64 bits */
> +		flags |= IORESOURCE_MEM | IORESOURCE_MEM_64;
> +		break;
>  	}
>  	if (w & 0x40000000)
>  		flags |= IORESOURCE_PREFETCH;
> diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c
> index 7bbdc26..defee61 100644
> --- a/arch/sparc/kernel/of_device_64.c
> +++ b/arch/sparc/kernel/of_device_64.c
> @@ -146,11 +146,12 @@ static unsigned long of_bus_pci_get_flags(const u32 *addr, unsigned long flags)
>  	case 0x01:
>  		flags |= IORESOURCE_IO;
>  		break;
> -
>  	case 0x02: /* 32 bits */
> -	case 0x03: /* 64 bits */
>  		flags |= IORESOURCE_MEM;
>  		break;
> +	case 0x03: /* 64 bits */
> +		flags |= IORESOURCE_MEM | IORESOURCE_MEM_64;
> +		break;
>  	}
>  	if (w & 0x40000000)
>  		flags |= IORESOURCE_PREFETCH;
> -- 
> 2.9.3
> 

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

* Re: [PATCH 04/13] sparc/PCI: Add IORESOURCE_MEM_64 for 64-bit resource in OF parsing
@ 2017-05-05 13:34     ` Bjorn Helgaas
  0 siblings, 0 replies; 33+ messages in thread
From: Bjorn Helgaas @ 2017-05-05 13:34 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt, Wei Yang,
	Khalid Aziz, linux-pci, linux-kernel, sparclinux

On Thu, Apr 20, 2017 at 10:04:51PM -0700, Yinghai Lu wrote:
> For device resource with PREF bit setting under bridge 64-bit pref resource,
> we need to make sure only set PREF for 64bit resource.
> 
> so this patch set IORESOUCE_MEM_64 for 64bit resource during OF device

s/IORESOUCE_MEM_64/IORESOURCE_MEM_64/

This misspelling occurs three times in the series; please fix them all.

> resource flags parsing.
> 
> Link: https://bugzilla.kernel.org/show_bug.cgi?id–261
> Link: https://bugzilla.kernel.org/show_bug.cgi?id–241
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: sparclinux@vger.kernel.org
> Tested-by: Khalid Aziz <khalid.aziz@oracle.com>
> ---
>  arch/sparc/kernel/of_device_32.c | 5 +++--
>  arch/sparc/kernel/of_device_64.c | 5 +++--
>  2 files changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c
> index 185aa96..3e9f273 100644
> --- a/arch/sparc/kernel/of_device_32.c
> +++ b/arch/sparc/kernel/of_device_32.c
> @@ -83,11 +83,12 @@ static unsigned long of_bus_pci_get_flags(const u32 *addr, unsigned long flags)
>  	case 0x01:
>  		flags |= IORESOURCE_IO;
>  		break;
> -
>  	case 0x02: /* 32 bits */
> -	case 0x03: /* 64 bits */
>  		flags |= IORESOURCE_MEM;
>  		break;
> +	case 0x03: /* 64 bits */
> +		flags |= IORESOURCE_MEM | IORESOURCE_MEM_64;
> +		break;
>  	}
>  	if (w & 0x40000000)
>  		flags |= IORESOURCE_PREFETCH;
> diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c
> index 7bbdc26..defee61 100644
> --- a/arch/sparc/kernel/of_device_64.c
> +++ b/arch/sparc/kernel/of_device_64.c
> @@ -146,11 +146,12 @@ static unsigned long of_bus_pci_get_flags(const u32 *addr, unsigned long flags)
>  	case 0x01:
>  		flags |= IORESOURCE_IO;
>  		break;
> -
>  	case 0x02: /* 32 bits */
> -	case 0x03: /* 64 bits */
>  		flags |= IORESOURCE_MEM;
>  		break;
> +	case 0x03: /* 64 bits */
> +		flags |= IORESOURCE_MEM | IORESOURCE_MEM_64;
> +		break;
>  	}
>  	if (w & 0x40000000)
>  		flags |= IORESOURCE_PREFETCH;
> -- 
> 2.9.3
> 

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

* Re: [PATCH 11/13] PCI: Add has_mem64 for struct host_bridge
  2017-05-04 23:04   ` Bjorn Helgaas
@ 2017-05-08  8:54     ` Christian König
  2017-05-08 13:25       ` Bjorn Helgaas
  0 siblings, 1 reply; 33+ messages in thread
From: Christian König @ 2017-05-08  8:54 UTC (permalink / raw)
  To: Bjorn Helgaas, Yinghai Lu
  Cc: Bjorn Helgaas, David Miller, Benjamin Herrenschmidt, Wei Yang,
	Khalid Aziz, linux-pci, linux-kernel

Am 05.05.2017 um 01:04 schrieb Bjorn Helgaas:
> [+cc Christian]
Thanks for that.

> [SNIP]
> I *think* this will be broken by the current implementation of
> Christian's patch to enable a 64-bit host bridge window:
>
>    https://lkml.kernel.org/r/1493890270-1188-5-git-send-email-deathsimple@vodafone.de
>
> because pci_register_host_bridge() runs before we scan the bus, and
> Christian's patch adds a quirk that runs when we enumerate the AMD
> host bridge device.
>
> If we apply this and Christian's patch, I think we could end up with
> a host bridge window above 4G, but with bridge->has_mem64 not set.
Yes, indeed. I can adjust my patch, but I would prefer not to do so.

I don't completely understand the background of this change, but from 
what I know how the BIOS (at least on X86) allocates resources it 
doesn't sounds correct to me.

Maybe we just need a Sparc specific quirk here instead of changing the 
common logic?

Regards,
Christian.

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

* Re: [PATCH 11/13] PCI: Add has_mem64 for struct host_bridge
  2017-05-08  8:54     ` Christian König
@ 2017-05-08 13:25       ` Bjorn Helgaas
  2017-05-09 11:38         ` Christian König
  0 siblings, 1 reply; 33+ messages in thread
From: Bjorn Helgaas @ 2017-05-08 13:25 UTC (permalink / raw)
  To: Christian König
  Cc: Yinghai Lu, Bjorn Helgaas, David Miller, Benjamin Herrenschmidt,
	Wei Yang, Khalid Aziz, linux-pci, linux-kernel

On Mon, May 08, 2017 at 10:54:55AM +0200, Christian König wrote:
> Am 05.05.2017 um 01:04 schrieb Bjorn Helgaas:
> >I *think* this will be broken by the current implementation of
> >Christian's patch to enable a 64-bit host bridge window:
> >
> >   https://lkml.kernel.org/r/1493890270-1188-5-git-send-email-deathsimple@vodafone.de
> >
> >because pci_register_host_bridge() runs before we scan the bus, and
> >Christian's patch adds a quirk that runs when we enumerate the AMD
> >host bridge device.
> >
> >If we apply this and Christian's patch, I think we could end up with
> >a host bridge window above 4G, but with bridge->has_mem64 not set.
> Yes, indeed. I can adjust my patch, but I would prefer not to do so.
> 
> I don't completely understand the background of this change, but
> from what I know how the BIOS (at least on X86) allocates resources
> it doesn't sounds correct to me.
> 
> Maybe we just need a Sparc specific quirk here instead of changing
> the common logic?

There's nothing in Yinghai's patch that's conceptually Sparc-specific,
so I would prefer not to artificially tie it to Sparc.

One possibility would be to compute has_mem64 when we need it instead
of caching it.

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

* Re: [PATCH 11/13] PCI: Add has_mem64 for struct host_bridge
  2017-05-08 13:25       ` Bjorn Helgaas
@ 2017-05-09 11:38         ` Christian König
  0 siblings, 0 replies; 33+ messages in thread
From: Christian König @ 2017-05-09 11:38 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Yinghai Lu, Bjorn Helgaas, David Miller, Benjamin Herrenschmidt,
	Wei Yang, Khalid Aziz, linux-pci, linux-kernel

Am 08.05.2017 um 15:25 schrieb Bjorn Helgaas:
> On Mon, May 08, 2017 at 10:54:55AM +0200, Christian König wrote:
>> Am 05.05.2017 um 01:04 schrieb Bjorn Helgaas:
>>> I *think* this will be broken by the current implementation of
>>> Christian's patch to enable a 64-bit host bridge window:
>>>
>>>    https://lkml.kernel.org/r/1493890270-1188-5-git-send-email-deathsimple@vodafone.de
>>>
>>> because pci_register_host_bridge() runs before we scan the bus, and
>>> Christian's patch adds a quirk that runs when we enumerate the AMD
>>> host bridge device.
>>>
>>> If we apply this and Christian's patch, I think we could end up with
>>> a host bridge window above 4G, but with bridge->has_mem64 not set.
>> Yes, indeed. I can adjust my patch, but I would prefer not to do so.
>>
>> I don't completely understand the background of this change, but
>> from what I know how the BIOS (at least on X86) allocates resources
>> it doesn't sounds correct to me.
>>
>> Maybe we just need a Sparc specific quirk here instead of changing
>> the common logic?
> There's nothing in Yinghai's patch that's conceptually Sparc-specific,
> so I would prefer not to artificially tie it to Sparc.

That's possible, I would need to take a closer look on them which I 
currently don't have time for.

It was more of a gut feeling considering that the current allocation 
code already looks rather complex.

> One possibility would be to compute has_mem64 when we need it instead
> of caching it.

Sounds like a good idea to me as well. I mean the code using this isn't 
time critical, isn't it?

And scanning the parent resources if a 64bit window can be found 
shouldn't be much overhead.

Christian.

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

end of thread, other threads:[~2017-05-09 11:38 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-21  5:04 [PATCH 00/13] PCI: sparc related 64bit resource fixup Yinghai Lu
2017-04-21  5:04 ` [PATCH 01/13] sparc/PCI: Use correct offset for bus address to resource Yinghai Lu
2017-04-21  5:04   ` Yinghai Lu
2017-04-21  5:04 ` [PATCH 02/13] PCI: Add pci_find_bus_resource() Yinghai Lu
2017-04-21  5:04 ` [PATCH 03/13] sparc/PCI: Reserve legacy mmio after PCI mmio Yinghai Lu
2017-04-21  5:04   ` Yinghai Lu
2017-05-03 22:03   ` Bjorn Helgaas
2017-05-03 22:03     ` Bjorn Helgaas
2017-04-21  5:04 ` [PATCH 04/13] sparc/PCI: Add IORESOURCE_MEM_64 for 64-bit resource in OF parsing Yinghai Lu
2017-04-21  5:04   ` Yinghai Lu
2017-05-05 13:34   ` Bjorn Helgaas
2017-05-05 13:34     ` Bjorn Helgaas
2017-04-21  5:04 ` [PATCH 05/13] sparc/PCI: Keep resource idx order with bridge register number Yinghai Lu
2017-04-21  5:04   ` Yinghai Lu
2017-04-21  5:04 ` [PATCH 06/13] powerpc/PCI: " Yinghai Lu
2017-04-21  5:04 ` [PATCH 07/13] powerpc/PCI: Add IORESOURCE_MEM_64 for 64-bit resource in OF parsing Yinghai Lu
2017-04-21  5:04 ` [PATCH 08/13] OF/PCI: Add IORESOURCE_MEM_64 for 64-bit resource Yinghai Lu
2017-04-24 14:12   ` Rob Herring
2017-04-24 14:12     ` Rob Herring
2017-04-21  5:04 ` [PATCH 09/13] PCI: Check pref compatible bit for mem64 resource of PCIe device Yinghai Lu
2017-04-21  5:04   ` Yinghai Lu
2017-05-04 21:19   ` Bjorn Helgaas
2017-05-04 21:19     ` Bjorn Helgaas
2017-04-21  5:04 ` [PATCH 10/13] PCI: Only treat non-pref mmio64 as pref if all bridges have MEM_64 Yinghai Lu
2017-05-04 21:43   ` Bjorn Helgaas
2017-04-21  5:04 ` [PATCH 11/13] PCI: Add has_mem64 for struct host_bridge Yinghai Lu
2017-05-04 23:04   ` Bjorn Helgaas
2017-05-08  8:54     ` Christian König
2017-05-08 13:25       ` Bjorn Helgaas
2017-05-09 11:38         ` Christian König
2017-04-21  5:04 ` [PATCH 12/13] PCI: Only treat non-pref mmio64 as pref if host bridge has mmio64 Yinghai Lu
2017-04-21  5:05 ` [PATCH 13/13] PCI: Restore pref MMIO allocation logic for host bridge without mmio64 Yinghai Lu
2017-05-05  1:24   ` Bjorn Helgaas

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.