PCI: of: Fix handling 64-bit PCI resources on non-LPAE kernels
Subsystems (2)
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().
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
PATCH 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
@@ -330,6 +330,12 @@ int of_pci_range_to_resource(struct of_pci_range *range, } res->start = port; }else { +#ifndef CONFIG_PHYS_ADDR_T_64BIT +if (upper_32_bits (range->cpu_addr)) { + err = -EINVAL ; + goto invalid_range; + } +#endif res->start = range->cpu_addr; } res->end = res->start + range->size -1 ;
Signature · 1 line
2.4.4
Rob Herring
maintainerRe: [PATCH 1/2] PCI: of: Add 64-bit address recognition without LPAE support
Quoted 28 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 -> 0x00000000MEM 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 -16This happens because
res->startassignment inof_pci_range_to_resource()truncates the upper part of the address, becauseres->startis ofphys_addr_ttype, which is 32-bit on non-LPAE kernels.This patch adds explicit recognition of 64-bit resources, preventing from potential problems when e. g.
0x8000001234would be converted to0x00001234.Signed-off-by Pavel Fedin <[email protected]>--- drivers/of/address.c | 6 ++++++ 1 file changed, 6 insertions(+)drivers/of/address.c +0
-0
drivers/of/address.c int of_pci_range_to_resource(struct of_pci_range *range, · line 334
Quoted 5 lines
drivers/of/address.c +2
-0@@ -330,6 +330,12 @@ int of_pci_range_to_resource(struct of_pci_range *range, } res->start = port; }else { +#ifndef CONFIG_PHYS_ADDR_T_64BIT +if (upper_32_bits (range->cpu_addr)) {
Drop the ifdef:
if ((sizeof(phys_addr_t) > 4) && upper_32_bits(range->cpu_addr)) {
Seems fine otherwise.
Quoted 10 lines
drivers/of/address.c +4
-1+ err = -EINVAL ; + goto invalid_range; + } +#endif res->start = range->cpu_addr; } res->end = res->start + range->size -1 ; --2.4.4
PATCH 2/2 PCI: of: Ignore resources with failed translation
In reply to Pavel FedinThis 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
@@ -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