From: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
To: Russell King - ARM Linux <linux@armlinux.org.uk>
Cc: "Baruch Siach" <baruch@tkos.co.il>,
"Lorenzo Pieralisi" <lorenzo.pieralisi@arm.com>,
"Jason Cooper" <jason@lakedaemon.net>,
linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
"Bjorn Helgaas" <bhelgaas@google.com>,
"Jan Kundrát" <jan.kundrat@cesnet.cz>,
linux-arm-kernel@lists.infradead.org
Subject: Re: [BISECTED] Regression: Solidrun Clearfog Base won't boot since "PCI: mvebu: Only remap I/O space if configured"
Date: Thu, 13 Sep 2018 09:45:15 +0200 [thread overview]
Message-ID: <20180913094515.351967bb@windsurf> (raw)
In-Reply-To: <20180912231050.GX30658@n2100.armlinux.org.uk>
Russell, Baruch, Jan,
On Thu, 13 Sep 2018 00:10:51 +0100, Russell King - ARM Linux wrote:
> It's probably the latter - the region is probably already mapped, that
> being the PCI IO region.
>
> The original driver was setup to call pci_ioremap_io() as the very
> last thing - and as the driver is non-removable, we were guaranteed
> to never tear down this mapping (which is sensible, it's published
> to userspace.)
>
> However, the current code calls pci_ioremap_io() much earlier, in
> a path where probe failures can occur. This breaks pci_ioremap_io()'s
> requirements - it must not be called more than once. So:
>
> ee1604381a37 ("PCI: mvebu: Only remap I/O space if configured")
>
> is basically incorrect - pci_ioremap_io() needs to move back to a
> place where it is only called in a path which will never fail.
> However, looking at the generic host bits, I'm not sure such a place
> exists in the new effort to make stuff more generic.
What about something like the below. I tested it, including the error
case by forcing an -EPROBE_DEFER. The new pci_unmap_io() is modeled
after pci_unmap_iospace(). Actually, I would prefer to use
pci_remap_iospace() and pci_unmap_iospace() but for now this API
doesn't allow overloading the memory type used for the mapping.
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 2cfbc531f63b..cee0e2be5ac7 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -185,6 +185,7 @@ static inline void pci_ioremap_set_mem_type(int mem_type) {}
#endif
extern int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr);
+extern void pci_unmap_io(unsigned int offset);
/*
* PCI configuration space mapping function.
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index fc91205ff46c..f3a4df44bb27 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -482,6 +482,14 @@ int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr)
}
EXPORT_SYMBOL_GPL(pci_ioremap_io);
+void pci_unmap_io(unsigned int offset)
+{
+ BUG_ON(offset + SZ_64K > IO_SPACE_LIMIT);
+
+ unmap_kernel_range(PCI_IO_VIRT_BASE + offset, SZ_64K);
+}
+EXPORT_SYMBOL_GPL(pci_unmap_io);
+
void __iomem *pci_remap_cfgspace(resource_size_t res_cookie, size_t size)
{
return arch_ioremap_caller(res_cookie, size, MT_UNCACHED,
diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index 50eb0729385b..772cff19c2ce 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -1145,7 +1145,6 @@ static int mvebu_pcie_parse_request_resources(struct mvebu_pcie *pcie)
{
struct device *dev = &pcie->pdev->dev;
struct device_node *np = dev->of_node;
- unsigned int i;
int ret;
INIT_LIST_HEAD(&pcie->resources);
@@ -1179,15 +1178,34 @@ static int mvebu_pcie_parse_request_resources(struct mvebu_pcie *pcie)
resource_size(&pcie->io) - 1);
pcie->realio.name = "PCI I/O";
- for (i = 0; i < resource_size(&pcie->realio); i += SZ_64K)
- pci_ioremap_io(i, pcie->io.start + i);
-
pci_add_resource(&pcie->resources, &pcie->realio);
}
return devm_request_pci_bus_resources(dev, &pcie->resources);
}
+static void mvebu_pcie_map_io(struct mvebu_pcie *pcie)
+{
+ int i;
+
+ if (resource_size(&pcie->io) == 0)
+ return;
+
+ for (i = 0; i < resource_size(&pcie->realio); i += SZ_64K)
+ pci_ioremap_io(i, pcie->io.start + i);
+}
+
+static void mvebu_pcie_unmap_io(struct mvebu_pcie *pcie)
+{
+ int i;
+
+ if (resource_size(&pcie->io) == 0)
+ return;
+
+ for (i = 0; i < resource_size(&pcie->realio); i += SZ_64K)
+ pci_unmap_io(i);
+}
+
static int mvebu_pcie_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -1258,6 +1276,8 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
pcie->nports = i;
+ mvebu_pcie_map_io(pcie);
+
list_splice_init(&pcie->resources, &bridge->windows);
bridge->dev.parent = dev;
bridge->sysdata = pcie;
@@ -1268,7 +1288,13 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
bridge->align_resource = mvebu_pcie_align_resource;
bridge->msi = pcie->msi;
- return pci_host_probe(bridge);
+ ret = pci_host_probe(bridge);
+ if (ret) {
+ mvebu_pcie_unmap_io(pcie);
+ return ret;
+ }
+
+ return 0;
}
static const struct of_device_id mvebu_pcie_of_match_table[] = {
--
Thomas Petazzoni, CTO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
WARNING: multiple messages have this Message-ID (diff)
From: thomas.petazzoni@bootlin.com (Thomas Petazzoni)
To: linux-arm-kernel@lists.infradead.org
Subject: [BISECTED] Regression: Solidrun Clearfog Base won't boot since "PCI: mvebu: Only remap I/O space if configured"
Date: Thu, 13 Sep 2018 09:45:15 +0200 [thread overview]
Message-ID: <20180913094515.351967bb@windsurf> (raw)
In-Reply-To: <20180912231050.GX30658@n2100.armlinux.org.uk>
Russell, Baruch, Jan,
On Thu, 13 Sep 2018 00:10:51 +0100, Russell King - ARM Linux wrote:
> It's probably the latter - the region is probably already mapped, that
> being the PCI IO region.
>
> The original driver was setup to call pci_ioremap_io() as the very
> last thing - and as the driver is non-removable, we were guaranteed
> to never tear down this mapping (which is sensible, it's published
> to userspace.)
>
> However, the current code calls pci_ioremap_io() much earlier, in
> a path where probe failures can occur. This breaks pci_ioremap_io()'s
> requirements - it must not be called more than once. So:
>
> ee1604381a37 ("PCI: mvebu: Only remap I/O space if configured")
>
> is basically incorrect - pci_ioremap_io() needs to move back to a
> place where it is only called in a path which will never fail.
> However, looking at the generic host bits, I'm not sure such a place
> exists in the new effort to make stuff more generic.
What about something like the below. I tested it, including the error
case by forcing an -EPROBE_DEFER. The new pci_unmap_io() is modeled
after pci_unmap_iospace(). Actually, I would prefer to use
pci_remap_iospace() and pci_unmap_iospace() but for now this API
doesn't allow overloading the memory type used for the mapping.
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 2cfbc531f63b..cee0e2be5ac7 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -185,6 +185,7 @@ static inline void pci_ioremap_set_mem_type(int mem_type) {}
#endif
extern int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr);
+extern void pci_unmap_io(unsigned int offset);
/*
* PCI configuration space mapping function.
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index fc91205ff46c..f3a4df44bb27 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -482,6 +482,14 @@ int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr)
}
EXPORT_SYMBOL_GPL(pci_ioremap_io);
+void pci_unmap_io(unsigned int offset)
+{
+ BUG_ON(offset + SZ_64K > IO_SPACE_LIMIT);
+
+ unmap_kernel_range(PCI_IO_VIRT_BASE + offset, SZ_64K);
+}
+EXPORT_SYMBOL_GPL(pci_unmap_io);
+
void __iomem *pci_remap_cfgspace(resource_size_t res_cookie, size_t size)
{
return arch_ioremap_caller(res_cookie, size, MT_UNCACHED,
diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index 50eb0729385b..772cff19c2ce 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -1145,7 +1145,6 @@ static int mvebu_pcie_parse_request_resources(struct mvebu_pcie *pcie)
{
struct device *dev = &pcie->pdev->dev;
struct device_node *np = dev->of_node;
- unsigned int i;
int ret;
INIT_LIST_HEAD(&pcie->resources);
@@ -1179,15 +1178,34 @@ static int mvebu_pcie_parse_request_resources(struct mvebu_pcie *pcie)
resource_size(&pcie->io) - 1);
pcie->realio.name = "PCI I/O";
- for (i = 0; i < resource_size(&pcie->realio); i += SZ_64K)
- pci_ioremap_io(i, pcie->io.start + i);
-
pci_add_resource(&pcie->resources, &pcie->realio);
}
return devm_request_pci_bus_resources(dev, &pcie->resources);
}
+static void mvebu_pcie_map_io(struct mvebu_pcie *pcie)
+{
+ int i;
+
+ if (resource_size(&pcie->io) == 0)
+ return;
+
+ for (i = 0; i < resource_size(&pcie->realio); i += SZ_64K)
+ pci_ioremap_io(i, pcie->io.start + i);
+}
+
+static void mvebu_pcie_unmap_io(struct mvebu_pcie *pcie)
+{
+ int i;
+
+ if (resource_size(&pcie->io) == 0)
+ return;
+
+ for (i = 0; i < resource_size(&pcie->realio); i += SZ_64K)
+ pci_unmap_io(i);
+}
+
static int mvebu_pcie_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -1258,6 +1276,8 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
pcie->nports = i;
+ mvebu_pcie_map_io(pcie);
+
list_splice_init(&pcie->resources, &bridge->windows);
bridge->dev.parent = dev;
bridge->sysdata = pcie;
@@ -1268,7 +1288,13 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
bridge->align_resource = mvebu_pcie_align_resource;
bridge->msi = pcie->msi;
- return pci_host_probe(bridge);
+ ret = pci_host_probe(bridge);
+ if (ret) {
+ mvebu_pcie_unmap_io(pcie);
+ return ret;
+ }
+
+ return 0;
}
static const struct of_device_id mvebu_pcie_of_match_table[] = {
--
Thomas Petazzoni, CTO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
WARNING: multiple messages have this Message-ID (diff)
From: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
To: Russell King - ARM Linux <linux@armlinux.org.uk>
Cc: "Baruch Siach" <baruch@tkos.co.il>,
"Jan Kundrát" <jan.kundrat@cesnet.cz>,
"Lorenzo Pieralisi" <lorenzo.pieralisi@arm.com>,
"Jason Cooper" <jason@lakedaemon.net>,
linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
"Bjorn Helgaas" <bhelgaas@google.com>,
linux-arm-kernel@lists.infradead.org
Subject: Re: [BISECTED] Regression: Solidrun Clearfog Base won't boot since "PCI: mvebu: Only remap I/O space if configured"
Date: Thu, 13 Sep 2018 09:45:15 +0200 [thread overview]
Message-ID: <20180913094515.351967bb@windsurf> (raw)
In-Reply-To: <20180912231050.GX30658@n2100.armlinux.org.uk>
Russell, Baruch, Jan,
On Thu, 13 Sep 2018 00:10:51 +0100, Russell King - ARM Linux wrote:
> It's probably the latter - the region is probably already mapped, that
> being the PCI IO region.
>
> The original driver was setup to call pci_ioremap_io() as the very
> last thing - and as the driver is non-removable, we were guaranteed
> to never tear down this mapping (which is sensible, it's published
> to userspace.)
>
> However, the current code calls pci_ioremap_io() much earlier, in
> a path where probe failures can occur. This breaks pci_ioremap_io()'s
> requirements - it must not be called more than once. So:
>
> ee1604381a37 ("PCI: mvebu: Only remap I/O space if configured")
>
> is basically incorrect - pci_ioremap_io() needs to move back to a
> place where it is only called in a path which will never fail.
> However, looking at the generic host bits, I'm not sure such a place
> exists in the new effort to make stuff more generic.
What about something like the below. I tested it, including the error
case by forcing an -EPROBE_DEFER. The new pci_unmap_io() is modeled
after pci_unmap_iospace(). Actually, I would prefer to use
pci_remap_iospace() and pci_unmap_iospace() but for now this API
doesn't allow overloading the memory type used for the mapping.
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 2cfbc531f63b..cee0e2be5ac7 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -185,6 +185,7 @@ static inline void pci_ioremap_set_mem_type(int mem_type) {}
#endif
extern int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr);
+extern void pci_unmap_io(unsigned int offset);
/*
* PCI configuration space mapping function.
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index fc91205ff46c..f3a4df44bb27 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -482,6 +482,14 @@ int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr)
}
EXPORT_SYMBOL_GPL(pci_ioremap_io);
+void pci_unmap_io(unsigned int offset)
+{
+ BUG_ON(offset + SZ_64K > IO_SPACE_LIMIT);
+
+ unmap_kernel_range(PCI_IO_VIRT_BASE + offset, SZ_64K);
+}
+EXPORT_SYMBOL_GPL(pci_unmap_io);
+
void __iomem *pci_remap_cfgspace(resource_size_t res_cookie, size_t size)
{
return arch_ioremap_caller(res_cookie, size, MT_UNCACHED,
diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index 50eb0729385b..772cff19c2ce 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -1145,7 +1145,6 @@ static int mvebu_pcie_parse_request_resources(struct mvebu_pcie *pcie)
{
struct device *dev = &pcie->pdev->dev;
struct device_node *np = dev->of_node;
- unsigned int i;
int ret;
INIT_LIST_HEAD(&pcie->resources);
@@ -1179,15 +1178,34 @@ static int mvebu_pcie_parse_request_resources(struct mvebu_pcie *pcie)
resource_size(&pcie->io) - 1);
pcie->realio.name = "PCI I/O";
- for (i = 0; i < resource_size(&pcie->realio); i += SZ_64K)
- pci_ioremap_io(i, pcie->io.start + i);
-
pci_add_resource(&pcie->resources, &pcie->realio);
}
return devm_request_pci_bus_resources(dev, &pcie->resources);
}
+static void mvebu_pcie_map_io(struct mvebu_pcie *pcie)
+{
+ int i;
+
+ if (resource_size(&pcie->io) == 0)
+ return;
+
+ for (i = 0; i < resource_size(&pcie->realio); i += SZ_64K)
+ pci_ioremap_io(i, pcie->io.start + i);
+}
+
+static void mvebu_pcie_unmap_io(struct mvebu_pcie *pcie)
+{
+ int i;
+
+ if (resource_size(&pcie->io) == 0)
+ return;
+
+ for (i = 0; i < resource_size(&pcie->realio); i += SZ_64K)
+ pci_unmap_io(i);
+}
+
static int mvebu_pcie_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -1258,6 +1276,8 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
pcie->nports = i;
+ mvebu_pcie_map_io(pcie);
+
list_splice_init(&pcie->resources, &bridge->windows);
bridge->dev.parent = dev;
bridge->sysdata = pcie;
@@ -1268,7 +1288,13 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
bridge->align_resource = mvebu_pcie_align_resource;
bridge->msi = pcie->msi;
- return pci_host_probe(bridge);
+ ret = pci_host_probe(bridge);
+ if (ret) {
+ mvebu_pcie_unmap_io(pcie);
+ return ret;
+ }
+
+ return 0;
}
static const struct of_device_id mvebu_pcie_of_match_table[] = {
--
Thomas Petazzoni, CTO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
next prev parent reply other threads:[~2018-09-13 7:45 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-12 16:11 [BISECTED] Regression: Solidrun Clearfog Base won't boot since "PCI: mvebu: Only remap I/O space if configured" Jan Kundrát
2018-09-12 16:11 ` Jan Kundrát
2018-09-12 16:11 ` Jan Kundrát
2018-09-12 18:49 ` Baruch Siach
2018-09-12 18:49 ` Baruch Siach
2018-09-12 18:49 ` Baruch Siach
2018-09-12 18:50 ` Thomas Petazzoni
2018-09-12 18:50 ` Thomas Petazzoni
2018-09-12 18:50 ` Thomas Petazzoni
2018-09-12 19:00 ` Jan Kundrát
2018-09-12 19:00 ` Jan Kundrát
2018-09-12 19:00 ` Jan Kundrát
2018-09-12 23:10 ` Russell King - ARM Linux
2018-09-12 23:10 ` Russell King - ARM Linux
2018-09-12 23:10 ` Russell King - ARM Linux
2018-09-13 3:19 ` Baruch Siach
2018-09-13 3:19 ` Baruch Siach
2018-09-13 3:19 ` Baruch Siach
2018-09-13 7:45 ` Thomas Petazzoni [this message]
2018-09-13 7:45 ` Thomas Petazzoni
2018-09-13 7:45 ` Thomas Petazzoni
2018-09-13 8:20 ` Jan Kundrát
2018-09-13 8:20 ` Jan Kundrát
2018-09-13 8:20 ` Jan Kundrát
2018-09-13 8:42 ` Thomas Petazzoni
2018-09-13 8:42 ` Thomas Petazzoni
2018-09-13 8:42 ` Thomas Petazzoni
2018-09-24 10:02 ` Jan Kundrát
2018-09-24 10:02 ` Jan Kundrát
2018-09-24 10:10 ` Thomas Petazzoni
2018-09-24 10:10 ` Thomas Petazzoni
2018-09-24 10:12 ` Russell King - ARM Linux
2018-09-24 10:12 ` Russell King - ARM Linux
2018-09-24 10:26 ` Thomas Petazzoni
2018-09-24 10:26 ` Thomas Petazzoni
2018-09-24 11:13 ` Russell King - ARM Linux
2018-09-24 11:13 ` Russell King - ARM Linux
2018-09-24 12:12 ` Thomas Petazzoni
2018-09-24 12:12 ` Thomas Petazzoni
2018-09-24 12:46 ` Lorenzo Pieralisi
2018-09-24 12:46 ` Lorenzo Pieralisi
2018-09-24 13:10 ` Thomas Petazzoni
2018-09-24 13:10 ` Thomas Petazzoni
2018-09-24 14:15 ` Lorenzo Pieralisi
2018-09-24 14:15 ` Lorenzo Pieralisi
2018-09-24 14:52 ` Thomas Petazzoni
2018-09-24 14:52 ` Thomas Petazzoni
2018-09-24 16:42 ` Lorenzo Pieralisi
2018-09-24 16:42 ` Lorenzo Pieralisi
2018-10-01 10:56 ` Jan Kundrát
2018-10-01 10:56 ` Jan Kundrát
2018-10-01 12:51 ` Thomas Petazzoni
2018-10-01 12:51 ` Thomas Petazzoni
2018-10-01 21:01 ` Bjorn Helgaas
2018-10-01 21:01 ` Bjorn Helgaas
2018-09-25 8:18 ` Andrew Murray
2018-09-25 8:18 ` Andrew Murray
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180913094515.351967bb@windsurf \
--to=thomas.petazzoni@bootlin.com \
--cc=baruch@tkos.co.il \
--cc=bhelgaas@google.com \
--cc=jan.kundrat@cesnet.cz \
--cc=jason@lakedaemon.net \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=lorenzo.pieralisi@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.