Skip to contentSkip to conversation

PCI: of: Fix handling 64-bit PCI resources on non-LPAE kernels

PATCH Applied Pavel Fedin 2 participants 6 messages Oct 8, 2015 – Oct 13, 2015

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

v2 cover PCI: of: Fix handling 64-bit PCI resources on non-LPAE kernels

The initial aim of this series is to fix long-standing problem with generic PCI host controller, triggered by ARM "virt" machine in the recent qemu. Since v2.4.50 qemu adds support for the second, large PCI MMIO window, which resides in 64-bit address space. This series addresses problems, which are triggered on non-LPAE kernels by this configuration.

These patches do not depend on each other and can be applied individually. The first adds missing recognition of 64-bit resources (which is actually a bug). The second one changes the code to ignore unaccessible resources instead of completely bailing out. Since it touches generic of_pci code, the fix is expected to be applied to all drivers which use of_pci_get_host_bridge_resources().

v1 => v2:
- Dropped #ifndef, use sizeof(resource_size_t) instead

Pavel Fedin (2):
PCI: of: Add 64-bit address recognition without LPAE support
PCI: of: Ignore resources with failed translation

 drivers/of/address.c | 6 ++++++
 drivers/of/of_pci.c  | 6 ++++--
 2 files changed, 10 insertions(+), 2 deletions(-)
Signature · 1 line
2.4.4
#1 lore raw

PATCH v2 1/2 PCI: of: Add 64-bit address recognition without LPAE support

If non-LPAE kernel is booted up on a machine with 64-bit PCI resources, PCI controller probe fails with:

PCI host bridge /pcie@10000000 ranges:
IO 0x3eff0000..0x3effffff -> 0x00000000
MEM 0x10000000..0x3efeffff -> 0x10000000
MEM 0x8000000000..0xffffffffff -> 0x8000000000
pci-host-generic 3f000000.pcie: resource collision: [mem 0x00000000-0xffffffff] conflicts with /pl011@9000000 [mem 0x09000000-0x09000fff]
pci-host-generic: probe of 3f000000.pcie failed with error -16

This happens because res->start assignment in of_pci_range_to_resource() truncates the upper part of the address, because res->start is of phys_addr_t type, which is 32-bit on non-LPAE kernels.

This patch adds explicit recognition of 64-bit resources, preventing from potential problems when e. g. 0x8000001234 would be converted to 0x00001234.

---
 drivers/of/address.c | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/of/address.c +6 -0
index 384574c..cd53fe4 100644
@@ -330,6 +330,12 @@ int of_pci_range_to_resource(struct of_pci_range *range,
 		}
 		res->start = port;
 	} else {
+		if ((sizeof(resource_size_t) < 8) &&
+		    upper_32_bits(range->cpu_addr)) {
+			err = -EINVAL;
+			goto invalid_range;
+		}
+
 		res->start = range->cpu_addr;
 	}
 	res->end = res->start + range->size - 1;
Signature · 1 line
2.4.4
Applied
#2 lore raw

Re: [PATCH v2 1/2] PCI: of: Add 64-bit address recognition without LPAE support

Quoted 14 lines · Pavel Fedin

If non-LPAE kernel is booted up on a machine with 64-bit PCI resources, PCI controller probe fails with:

PCI host bridge /pcie@10000000 ranges:

   IO 0x3eff0000..0x3effffff -> 0x00000000

MEM 0x10000000..0x3efeffff -> 0x10000000
MEM 0x8000000000..0xffffffffff -> 0x8000000000
pci-host-generic 3f000000.pcie: resource collision: [mem 0x00000000-0xffffffff] conflicts with /pl011@9000000 [mem 0x09000000-0x09000fff]
pci-host-generic: probe of 3f000000.pcie failed with error -16

This happens because res->start assignment in of_pci_range_to_resource() truncates the upper part of the address, because res->start is of phys_addr_t type, which is 32-bit on non-LPAE kernels.

Quoted 5 lines

This patch adds explicit recognition of 64-bit resources, preventing from potential problems when e. g. 0x8000001234 would be converted to 0x00001234.

Applied, thanks.

Rob

Quoted 24 lines
---
 drivers/of/address.c | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/of/address.c +6 -1
index 384574c..cd53fe4 100644
@@ -330,6 +330,12 @@ int of_pci_range_to_resource(struct of_pci_range *range,
                }
                res->start = port;
        } else {
+               if ((sizeof(resource_size_t) < 8) &&
+                   upper_32_bits(range->cpu_addr)) {
+                       err = -EINVAL;
+                       goto invalid_range;
+               }
+
                res->start = range->cpu_addr;
        }
        res->end = res->start + range->size - 1;
--

2.4.4

#3 lore raw

PATCH v2 2/2 PCI: of: Ignore resources with failed translation

In reply to Pavel Fedin

This patch allows PCI host controller to function even if part of resources is unusable for some reason. An example is non-LPAE kernel on a machine which has some 64-bit resources. Unusable resources will be just skipped instead of a complete failure.

---
 drivers/of/of_pci.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/of/of_pci.c +4 -2
index 5751dc5..ea7c2b6 100644
@@ -223,8 +223,10 @@ int of_pci_get_host_bridge_resources(struct device_node *dev,
 		}
 
 		err = of_pci_range_to_resource(&range, dev, res);
-		if (err)
-			goto conversion_failed;
+		if (err) {
+			kfree(res);
+			continue;
+		}
 
 		if (resource_type(res) == IORESOURCE_IO) {
 			if (!io_base) {
Signature · 1 line
2.4.4
Applied
#4 lore raw

Re: [PATCH v2 2/2] PCI: of: Ignore resources with failed translation

Quoted 6 lines · Pavel Fedin

This patch allows PCI host controller to function even if part of resources is unusable for some reason. An example is non-LPAE kernel on a machine which has some 64-bit resources. Unusable resources will be just skipped instead of a complete failure.

Applied, thanks.

Rob

Quoted 24 lines
---
 drivers/of/of_pci.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/of/of_pci.c +4 -3
index 5751dc5..ea7c2b6 100644
@@ -223,8 +223,10 @@ int of_pci_get_host_bridge_resources(struct device_node *dev,
                }
 
                err = of_pci_range_to_resource(&range, dev, res);
-               if (err)
-                       goto conversion_failed;
+               if (err) {
+                       kfree(res);
+                       continue;
+               }
 
                if (resource_type(res) == IORESOURCE_IO) {
                        if (!io_base) {
--

2.4.4

#5 lore raw
In reply to Pavel Fedin
Quoted 27 lines · Pavel Fedin

The initial aim of this series is to fix long-standing problem with generic PCI host controller, triggered by ARM "virt" machine in the recent qemu. Since v2.4.50 qemu adds support for the second, large PCI MMIO window, which resides in 64-bit address space. This series addresses problems, which are triggered on non-LPAE kernels by this configuration.

These patches do not depend on each other and can be applied individually. The first adds missing recognition of 64-bit resources (which is actually a bug). The second one changes the code to ignore unaccessible resources instead of completely bailing out. Since it touches generic of_pci code, the fix is expected to be applied to all drivers which use of_pci_get_host_bridge_resources().

v1 => v2:
- Dropped #ifndef, use sizeof(resource_size_t) instead

Pavel Fedin (2):
PCI: of: Add 64-bit address recognition without LPAE support
PCI: of: Ignore resources with failed translation

 drivers/of/address.c | 6 ++++++
 drivers/of/of_pci.c  | 6 ++++--
 2 files changed, 10 insertions(+), 2 deletions(-)

--
2.4.4