* [v4 PATCH 1/1] PCI: of: fix non-prefetchable region address range check. @ 2025-06-20 9:32 Wannes Bouwen (Nokia) 2025-07-15 21:33 ` Bjorn Helgaas 0 siblings, 1 reply; 3+ messages in thread From: Wannes Bouwen (Nokia) @ 2025-06-20 9:32 UTC (permalink / raw) To: Bjorn Helgaas, Manivannan Sadhasivam Cc: Rob Herring, Vidya Sagar, lorenzo.pieralisi@arm.com, linux-pci@vger.kernel.org [v4 PATCH 1/1] PCI: of: fix non-prefetchable region address range check. According to the PCIe spec (PCIe r6.3, sec 7.5.1.3.8), non-prefetchable memory supports only 32-bit host bridge windows (both base address as limit address). In the kernel there is a check that prints a warning if a non-prefetchable resource's size exceeds the 32-bit limit. The check currently checks the size of the resource, while actually the check should be done on the PCIe end address of the non-prefetchable window. Move the check to devm_of_pci_get_host_bridge_resources() where the PCIe addresses are available and use the end address instead of the size of the window. Fixes: fede8526cc48 (PCI: of: Warn if non-prefetchable memory aperture size is > 32-bit) Signed-off-by: Wannes Bouwen <wannes.bouwen@nokia.com> --- v4: - Update warning text v3: - Update subject and description + add changelog v2: - Use PCI address range instead of window size to check that window is within a 32bit boundary. --- drivers/pci/of.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/pci/of.c b/drivers/pci/of.c index 3579265f1198..16405985a53a 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -400,6 +400,13 @@ static int devm_of_pci_get_host_bridge_resources(struct device *dev, *io_base = range.cpu_addr; } else if (resource_type(res) == IORESOURCE_MEM) { res->flags &= ~IORESOURCE_MEM_64; + + if (!(res->flags & IORESOURCE_PREFETCH)) + if (upper_32_bits(range.pci_addr + range.size - 1)) + dev_warn(dev, + "host bridge non-prefetchable window: pci range end address exceeds 32 bit boundary %pR" + " (pci address range [%#012llx-%#012llx])\n", + res, range.pci_addr, range.pci_addr + range.size - 1); } pci_add_resource_offset(resources, res, res->start - range.pci_addr); @@ -622,10 +629,6 @@ static int pci_parse_request_of_pci_ranges(struct device *dev, case IORESOURCE_MEM: res_valid |= !(res->flags & IORESOURCE_PREFETCH); - if (!(res->flags & IORESOURCE_PREFETCH)) - if (upper_32_bits(resource_size(res))) - dev_warn(dev, "Memory resource size exceeds max for 32 bits\n"); - break; } } -- 2.43.5 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [v4 PATCH 1/1] PCI: of: fix non-prefetchable region address range check. 2025-06-20 9:32 [v4 PATCH 1/1] PCI: of: fix non-prefetchable region address range check Wannes Bouwen (Nokia) @ 2025-07-15 21:33 ` Bjorn Helgaas 2025-07-17 8:33 ` Wannes Bouwen (Nokia) 0 siblings, 1 reply; 3+ messages in thread From: Bjorn Helgaas @ 2025-07-15 21:33 UTC (permalink / raw) To: Wannes Bouwen (Nokia) Cc: Manivannan Sadhasivam, Rob Herring, Vidya Sagar, lorenzo.pieralisi@arm.com, linux-pci@vger.kernel.org In subject, capitalize "Fix" and drop period at end. On Fri, Jun 20, 2025 at 09:32:35AM +0000, Wannes Bouwen (Nokia) wrote: > > [v4 PATCH 1/1] PCI: of: fix non-prefetchable region address range check. Drop this. > According to the PCIe spec (PCIe r6.3, sec 7.5.1.3.8), non-prefetchable > memory supports only 32-bit host bridge windows (both base address as > limit address). 7.5.1.3.8 is about PCI-to-PCI bridge windows, not host bridge windows. I'm confused about what's going on here. The word "prefetch" doesn't even appear in PCIe r7.0, but historically, issue was that we have to be careful about putting a non-prefetchable BAR in a prefetchable window because a read (which might be a prefetch) in a non-prefetchable BAR is allowed to have side effects. But if we put a prefetchable BAR in a non-prefetchable window, nothing bad happens other than performance might be bad. Are we trying to warn about a potential performance problem? Or is there some functional problem here? > In the kernel there is a check that prints a warning if a > non-prefetchable resource's size exceeds the 32-bit limit. > > The check currently checks the size of the resource, while actually the > check should be done on the PCIe end address of the non-prefetchable > window. > > Move the check to devm_of_pci_get_host_bridge_resources() where the PCIe > addresses are available and use the end address instead of the size of > the window. Are you seeing an issue here? Can we include a dmesg snippet that illustrates it? > Fixes: fede8526cc48 (PCI: of: Warn if non-prefetchable memory aperture > size is > 32-bit) > Signed-off-by: Wannes Bouwen <wannes.bouwen@nokia.com> > --- > > v4: > - Update warning text > > v3: > - Update subject and description + add changelog > > v2: > - Use PCI address range instead of window size to check that window is > within a 32bit boundary. > > --- > drivers/pci/of.c | 11 +++++++---- > 1 file changed, 7 insertions(+), 4 deletions(-) > > diff --git a/drivers/pci/of.c b/drivers/pci/of.c > index 3579265f1198..16405985a53a 100644 > --- a/drivers/pci/of.c > +++ b/drivers/pci/of.c > @@ -400,6 +400,13 @@ static int devm_of_pci_get_host_bridge_resources(struct device *dev, > *io_base = range.cpu_addr; > } else if (resource_type(res) == IORESOURCE_MEM) { > res->flags &= ~IORESOURCE_MEM_64; > + > + if (!(res->flags & IORESOURCE_PREFETCH)) > + if (upper_32_bits(range.pci_addr + range.size - 1)) > + dev_warn(dev, > + "host bridge non-prefetchable window: pci range end address exceeds 32 bit boundary %pR" > + " (pci address range [%#012llx-%#012llx])\n", > + res, range.pci_addr, range.pci_addr + range.size - 1); I gave you bad advice because I hadn't looked earlier in this function. devm_of_pci_get_host_bridge_resources() printed this earlier: MEM %#012llx..%#012llx -> %#012llx where the first part is basically the %pR information in a different format and the last part is the bus address, and I think a warning here should look similar, e.g., dev_warn(dev, "Bus address %#012llx..%#012llx end is past 32-bit boundary\n", > } > > pci_add_resource_offset(resources, res, res->start - range.pci_addr); > @@ -622,10 +629,6 @@ static int pci_parse_request_of_pci_ranges(struct device *dev, > case IORESOURCE_MEM: > res_valid |= !(res->flags & IORESOURCE_PREFETCH); > > - if (!(res->flags & IORESOURCE_PREFETCH)) > - if (upper_32_bits(resource_size(res))) > - dev_warn(dev, "Memory resource size exceeds max for 32 bits\n"); > - > break; > } > } > -- > 2.43.5 ^ permalink raw reply [flat|nested] 3+ messages in thread
* RE: [v4 PATCH 1/1] PCI: of: fix non-prefetchable region address range check. 2025-07-15 21:33 ` Bjorn Helgaas @ 2025-07-17 8:33 ` Wannes Bouwen (Nokia) 0 siblings, 0 replies; 3+ messages in thread From: Wannes Bouwen (Nokia) @ 2025-07-17 8:33 UTC (permalink / raw) To: Bjorn Helgaas Cc: Manivannan Sadhasivam, Rob Herring, Vidya Sagar, lorenzo.pieralisi@arm.com, linux-pci@vger.kernel.org > In subject, capitalize "Fix" and drop period at end. > Okay. > On Fri, Jun 20, 2025 at 09:32:35AM +0000, Wannes Bouwen (Nokia) wrote: > > > > [v4 PATCH 1/1] PCI: of: fix non-prefetchable region address range check. > > Drop this. > Ok, will drop. > > According to the PCIe spec (PCIe r6.3, sec 7.5.1.3.8), > > non-prefetchable memory supports only 32-bit host bridge windows (both > > base address as limit address). > > 7.5.1.3.8 is about PCI-to-PCI bridge windows, not host bridge windows. > How I understand it: - Section 7.5.1.3 Type 1 Configuration Space Header is applicable for PCIe Switch and Root Ports. Logically a PCIe port acts as a PCI-PCI bridge. - The term host bridge windows is indeed maybe not fully correct here. It has to do with the limitation on the memory address / memory range in the PCIe Switch / Root ports to 32 bits. - The host bridge windows are used to configure the Type 1 Configuration Space in the end. > I'm confused about what's going on here. The word "prefetch" doesn't even > appear in PCIe r7.0, but historically, issue was that we have to be careful about > putting a non-prefetchable BAR in a prefetchable window because a read > (which might be a prefetch) in a non-prefetchable BAR is allowed to have side > effects. > > But if we put a prefetchable BAR in a non-prefetchable window, nothing bad > happens other than performance might be bad. > > Are we trying to warn about a potential performance problem? Or is there > some functional problem here? > The warning here is just about the size of the 32 bit window in the Type 1 Configuration Space Header. It has in principle nothing to do with how we map the BARs on these windows. > > In the kernel there is a check that prints a warning if a > > non-prefetchable resource's size exceeds the 32-bit limit. > > > > The check currently checks the size of the resource, while actually > > the check should be done on the PCIe end address of the > > non-prefetchable window. > > > > Move the check to devm_of_pci_get_host_bridge_resources() where the > > PCIe addresses are available and use the end address instead of the > > size of the window. > > Are you seeing an issue here? Can we include a dmesg snippet that illustrates > it? > We see below warning because we define a 4 GiB non-prefetchable host bridge window. [ 341.213850] armada8k-pcie f2620000.pcie: host bridge /cp0/pcie@f2620000 ranges: [ 341.213883] armada8k-pcie f2620000.pcie: MEM 0x0400000000..0x04ffffffff -> 0x0000000000 [ 341.213894] armada8k-pcie f2620000.pcie: MEM 0x0500000000..0x05ffffffff -> 0x0100000000 [ 341.213903] armada8k-pcie f2620000.pcie: Memory resource size exceeds max for 32 bits > > Fixes: fede8526cc48 (PCI: of: Warn if non-prefetchable memory aperture > > size is > 32-bit) > > Signed-off-by: Wannes Bouwen <wannes.bouwen@nokia.com> > > --- > > > > v4: > > - Update warning text > > > > v3: > > - Update subject and description + add changelog > > > > v2: > > - Use PCI address range instead of window size to check that window is > > within a 32bit boundary. > > > > --- > > drivers/pci/of.c | 11 +++++++---- > > 1 file changed, 7 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/pci/of.c b/drivers/pci/of.c index > > 3579265f1198..16405985a53a 100644 > > --- a/drivers/pci/of.c > > +++ b/drivers/pci/of.c > > @@ -400,6 +400,13 @@ static int > devm_of_pci_get_host_bridge_resources(struct device *dev, > > *io_base = range.cpu_addr; > > } else if (resource_type(res) == IORESOURCE_MEM) { > > res->flags &= ~IORESOURCE_MEM_64; > > + > > + if (!(res->flags & IORESOURCE_PREFETCH)) > > + if (upper_32_bits(range.pci_addr + range.size - 1)) > > + dev_warn(dev, > > + "host bridge non-prefetchable window: pci range > end address exceeds 32 bit boundary %pR" > > + " (pci address range [%#012llx-%#012llx])\n", > > + res, range.pci_addr, > > + range.pci_addr + range.size - 1); > > I gave you bad advice because I hadn't looked earlier in this function. > devm_of_pci_get_host_bridge_resources() printed this > earlier: > > MEM %#012llx..%#012llx -> %#012llx > > where the first part is basically the %pR information in a different format and > the last part is the bus address, and I think a warning here should look similar, > e.g., > > dev_warn(dev, "Bus address %#012llx..%#012llx end is past 32-bit > boundary\n", > I will update the warning. > > } > > > > pci_add_resource_offset(resources, res, res->start - > > range.pci_addr); @@ -622,10 +629,6 @@ static int > pci_parse_request_of_pci_ranges(struct device *dev, > > case IORESOURCE_MEM: > > res_valid |= !(res->flags & > > IORESOURCE_PREFETCH); > > > > - if (!(res->flags & IORESOURCE_PREFETCH)) > > - if (upper_32_bits(resource_size(res))) > > - dev_warn(dev, "Memory resource size exceeds max for > 32 bits\n"); > > - > > break; > > } > > } > > -- > > 2.43.5 ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-07-17 8:33 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-06-20 9:32 [v4 PATCH 1/1] PCI: of: fix non-prefetchable region address range check Wannes Bouwen (Nokia) 2025-07-15 21:33 ` Bjorn Helgaas 2025-07-17 8:33 ` Wannes Bouwen (Nokia)
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).