On Thu, 10 Sep 2026, Ard Biesheuvel wrote: > > On Thu, 10 Sep 2026, at 19:31, Ilpo Järvinen wrote: > > On Thu, 10 Sep 2026, Ard Biesheuvel wrote: > > > >> From: Ard Biesheuvel > >> > >> The prefetchable vs. non-prefetchable distinction is a relic of > >> conventional PCI, to denote from which regions PCI-PCI bridges were > >> permitted to perform speculative readahead. > >> > >> For software compatibility reasons, PCI Express inherited the Type 1 > >> header and models PCIe root ports as PCI-PCI bridges. However, this > >> readahead behavior does not exist in PCIe, and so this distinction has > >> mostly become meaningless on the bridge level. > >> > >> As per the PCIe r6.3 ECN "Removing Prefetchable Terminology", the > >> 'prefetchable' designation has been removed from the specification > >> entirely, on the basis that it is obsolete, and is being abused to > >> inform memory mapping attributes and other device/BAR level properties > >> that it was never intended for. > >> > >> Given the limited range for non-prefetchable windows in the Type 1 > >> header, and the fact that the distinction no longer exists for PCIe, > >> resource allocation performed by firmware may result in non-prefetchable > >> 64-bit BARs being allocated inside prefetchable bridge windows. > >> > >> Linux rejects such allocations ("can't claim; no compatible bridge > >> window") when it encounters them, but will usually fail to produce an > >> alternative allocation, given that firmware wouldn't have placed them > >> there in the first place if there was sufficient space in the > >> non-prefetchable window. > >> > >> So at the very least, let's not reject such allocations when they were > >> made by the firmware. > >> > >> Cc: Bjorn Helgaas > >> Cc: "Ilpo Järvinen" > >> Signed-off-by: Ard Biesheuvel > >> --- > >> Link: https://github.com/tianocore/edk2/issues/13104 > >> > >> drivers/pci/pci.c | 3 ++- > >> include/linux/pci.h | 4 ++-- > >> 2 files changed, 4 insertions(+), 3 deletions(-) > >> > >> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c > >> index b2879a6be5f8..e33eb9f3a139 100644 > >> --- a/drivers/pci/pci.c > >> +++ b/drivers/pci/pci.c > >> @@ -761,7 +761,8 @@ struct resource *pci_find_parent_resource(const struct pci_dev *dev, > >> * not, the allocator made a mistake. > >> */ > >> if (r->flags & IORESOURCE_PREFETCH && > >> - !(res->flags & IORESOURCE_PREFETCH)) > >> + !(res->flags & IORESOURCE_PREFETCH) && > >> + !pci_is_pcie(dev)) > >> return NULL; > >> > >> /* > > > > I was more thinking along the lines of always setting IORESOURCE_PREFETCH > > for 64-bit BARs on PCIe devices but I've not had time to look at that/test > > how many things would break as a result. ...It would seem much simpler > > solution to differentiate PCI from PCIe while keeping the existing logic > > without adding similar pci_is_pcie() checks everywhere. > > > > I agree that the code changes would be much simpler. > > However, would this impact the PCI metadata observed by all consumers, > including userspace, Yes, it will impact userspace. But quoting you from above: "is being abused to inform memory mapping attributes and other device/BAR level properties that it was never intended for." What does the userspace then do with the information? Does it qualify under "it was never intended for"? > and drivers that may expect a certain BAR layout, ??? Would that even be spec compliant?? > and/or base decisions about memory attributes on this? The point is to consider them 64-bit window eligible so yes, kernel would definitely be basing decision on that but that's intentional. > In particular, I am concerned about non-prefetchable BARs that actually > have side effects on read, being mapped with WC (or Normal-NC on arm64) > semantics, where the interconnect may widen, combine or reorder accesses. So on a more concrete terms, you're referring to the check in proc_bus_pci_mmap()? And the one in __pci_resource_attr_is_visible() + pci_dev_resource_wc_is_visible()? I suppose that wouldn't work then. So if just setting IORESOURCE_PREFETCH is not workable, how about adding a getter for res->flags which adds IORESOURCE_PREFETCH into the returned flags if it's PCIe device and (in the end) use the raw value only in those places that actually care about wc distinction. What I don't want to see us adding that pci_is_pcie() everywhere. -- i.