On s390 today we overwrite the PCI BAR resource address to either an
artificial cookie address or MIO address. However this address is different
from the bus address of the BARs programmed by firmware. The artificial
cookie address was created to index into an array of function handles
(zpci_iomap_start). The MIO (mapped I/O) addresses are provided by firmware
but maybe different from the bus addresses. This creates an issue when
trying to convert the BAR resource address to bus address using the generic
pcibios_resource_to_bus().
Implement an architecture specific pcibios_resource_to_bus() function to
correctly translate PCI BAR resource addresses to bus addresses for s390.
Similarly add architecture specific pcibios_bus_to_resource function to do
the reverse translation.
Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Farhan Ali <alifm@linux.ibm.com>
---
arch/s390/pci/pci.c | 74 +++++++++++++++++++++++++++++++++++++++
drivers/pci/host-bridge.c | 8 ++---
2 files changed, 78 insertions(+), 4 deletions(-)
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 2a430722cbe4..87077e510266 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -272,6 +272,80 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
return 0;
}
+void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,
+ struct resource *res)
+{
+ struct zpci_bus *zbus = bus->sysdata;
+ struct zpci_bar_struct *zbar;
+ struct zpci_dev *zdev;
+
+ region->start = res->start;
+ region->end = res->end;
+
+ for (int i = 0; i < ZPCI_FUNCTIONS_PER_BUS; i++) {
+ int j = 0;
+
+ zbar = NULL;
+ zdev = zbus->function[i];
+ if (!zdev)
+ continue;
+
+ for (j = 0; j < PCI_STD_NUM_BARS; j++) {
+ if (zdev->bars[j].res->start == res->start &&
+ zdev->bars[j].res->end == res->end &&
+ res->flags & IORESOURCE_MEM) {
+ zbar = &zdev->bars[j];
+ break;
+ }
+ }
+
+ if (zbar) {
+ /* only MMIO is supported */
+ region->start = zbar->val & PCI_BASE_ADDRESS_MEM_MASK;
+ if (zbar->val & PCI_BASE_ADDRESS_MEM_TYPE_64)
+ region->start |= (u64)zdev->bars[j + 1].val << 32;
+
+ region->end = region->start + (1UL << zbar->size) - 1;
+ return;
+ }
+ }
+}
+
+void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res,
+ struct pci_bus_region *region)
+{
+ struct zpci_bus *zbus = bus->sysdata;
+ struct zpci_dev *zdev;
+ resource_size_t start, end;
+
+ res->start = region->start;
+ res->end = region->end;
+
+ for (int i = 0; i < ZPCI_FUNCTIONS_PER_BUS; i++) {
+ zdev = zbus->function[i];
+ if (!zdev || !zdev->has_resources)
+ continue;
+
+ for (int j = 0; j < PCI_STD_NUM_BARS; j++) {
+ if (!zdev->bars[j].size)
+ continue;
+
+ /* only MMIO is supported */
+ start = zdev->bars[j].val & PCI_BASE_ADDRESS_MEM_MASK;
+ if (zdev->bars[j].val & PCI_BASE_ADDRESS_MEM_TYPE_64)
+ start |= (u64)zdev->bars[j + 1].val << 32;
+
+ end = start + (1UL << zdev->bars[j].size) - 1;
+
+ if (start == region->start && end == region->end) {
+ res->start = zdev->bars[j].res->start;
+ res->end = zdev->bars[j].res->end;
+ return;
+ }
+ }
+ }
+}
+
void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size,
pgprot_t prot)
{
diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c
index be5ef6516cff..aed031b8a9f3 100644
--- a/drivers/pci/host-bridge.c
+++ b/drivers/pci/host-bridge.c
@@ -49,8 +49,8 @@ void pci_set_host_bridge_release(struct pci_host_bridge *bridge,
}
EXPORT_SYMBOL_GPL(pci_set_host_bridge_release);
-void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,
- struct resource *res)
+void __weak pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,
+ struct resource *res)
{
struct pci_host_bridge *bridge = pci_find_host_bridge(bus);
struct resource_entry *window;
@@ -74,8 +74,8 @@ static bool region_contains(struct pci_bus_region *region1,
return region1->start <= region2->start && region1->end >= region2->end;
}
-void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res,
- struct pci_bus_region *region)
+void __weak pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res,
+ struct pci_bus_region *region)
{
struct pci_host_bridge *bridge = pci_find_host_bridge(bus);
struct resource_entry *window;
--
2.43.0
[+cc Ilpo just for awareness; I assume there's nothing Linux can
actually *do* with s390 PCI resources?]
On Mon, Mar 16, 2026 at 12:15:37PM -0700, Farhan Ali wrote:
> On s390 today we overwrite the PCI BAR resource address to either an
> artificial cookie address or MIO address. However this address is different
> from the bus address of the BARs programmed by firmware. The artificial
> cookie address was created to index into an array of function handles
> (zpci_iomap_start). The MIO (mapped I/O) addresses are provided by firmware
> but maybe different from the bus addresses. This creates an issue when
> trying to convert the BAR resource address to bus address using the generic
> pcibios_resource_to_bus().
>
> Implement an architecture specific pcibios_resource_to_bus() function to
> correctly translate PCI BAR resource addresses to bus addresses for s390.
> Similarly add architecture specific pcibios_bus_to_resource function to do
> the reverse translation.
1) It's not clear to me *why* we need these arch-specific versions.
We went to a lot of trouble to make these interfaces generic, and I'll
be really sad if they have to be arch-specific again. I don't see any
direct uses of these in the series. In any case, some reference to
the user and the actual problem this solves would help.
2) I'm kind of concerned that the "unusual" s390 PCI resources will be
unintelligible to people who are used to reading lspci or dmesg logs
from non-s390 systems, and they might confuse the PCI core resource
assignment code. I guess there's not really a concept of a PCI host
bridge on s390, there's no bus hierarchy, and no visible PCI-to-PCI
bridges, so no windows? Can you use PCIe switches at all?
3) Maybe this patch should be reordered to be closer to the patch that
needs these? I don't think it's related to the "PCI: Avoid saving
config space state if inaccessible" and PCI: Add additional checks for
flr reset" patches.
> Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
> Signed-off-by: Farhan Ali <alifm@linux.ibm.com>
> ---
> arch/s390/pci/pci.c | 74 +++++++++++++++++++++++++++++++++++++++
> drivers/pci/host-bridge.c | 8 ++---
> 2 files changed, 78 insertions(+), 4 deletions(-)
>
> diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
> index 2a430722cbe4..87077e510266 100644
> --- a/arch/s390/pci/pci.c
> +++ b/arch/s390/pci/pci.c
> @@ -272,6 +272,80 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
> return 0;
> }
>
> +void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,
> + struct resource *res)
> +{
> + struct zpci_bus *zbus = bus->sysdata;
> + struct zpci_bar_struct *zbar;
> + struct zpci_dev *zdev;
> +
> + region->start = res->start;
> + region->end = res->end;
> +
> + for (int i = 0; i < ZPCI_FUNCTIONS_PER_BUS; i++) {
> + int j = 0;
> +
> + zbar = NULL;
> + zdev = zbus->function[i];
> + if (!zdev)
> + continue;
> +
> + for (j = 0; j < PCI_STD_NUM_BARS; j++) {
> + if (zdev->bars[j].res->start == res->start &&
> + zdev->bars[j].res->end == res->end &&
> + res->flags & IORESOURCE_MEM) {
> + zbar = &zdev->bars[j];
> + break;
> + }
> + }
> +
> + if (zbar) {
> + /* only MMIO is supported */
> + region->start = zbar->val & PCI_BASE_ADDRESS_MEM_MASK;
> + if (zbar->val & PCI_BASE_ADDRESS_MEM_TYPE_64)
> + region->start |= (u64)zdev->bars[j + 1].val << 32;
> +
> + region->end = region->start + (1UL << zbar->size) - 1;
> + return;
> + }
> + }
> +}
> +
> +void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res,
> + struct pci_bus_region *region)
> +{
> + struct zpci_bus *zbus = bus->sysdata;
> + struct zpci_dev *zdev;
> + resource_size_t start, end;
> +
> + res->start = region->start;
> + res->end = region->end;
> +
> + for (int i = 0; i < ZPCI_FUNCTIONS_PER_BUS; i++) {
> + zdev = zbus->function[i];
> + if (!zdev || !zdev->has_resources)
> + continue;
> +
> + for (int j = 0; j < PCI_STD_NUM_BARS; j++) {
> + if (!zdev->bars[j].size)
> + continue;
> +
> + /* only MMIO is supported */
> + start = zdev->bars[j].val & PCI_BASE_ADDRESS_MEM_MASK;
> + if (zdev->bars[j].val & PCI_BASE_ADDRESS_MEM_TYPE_64)
> + start |= (u64)zdev->bars[j + 1].val << 32;
> +
> + end = start + (1UL << zdev->bars[j].size) - 1;
> +
> + if (start == region->start && end == region->end) {
> + res->start = zdev->bars[j].res->start;
> + res->end = zdev->bars[j].res->end;
> + return;
> + }
> + }
> + }
> +}
> +
> void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size,
> pgprot_t prot)
> {
> diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c
> index be5ef6516cff..aed031b8a9f3 100644
> --- a/drivers/pci/host-bridge.c
> +++ b/drivers/pci/host-bridge.c
> @@ -49,8 +49,8 @@ void pci_set_host_bridge_release(struct pci_host_bridge *bridge,
> }
> EXPORT_SYMBOL_GPL(pci_set_host_bridge_release);
>
> -void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,
> - struct resource *res)
> +void __weak pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,
> + struct resource *res)
> {
> struct pci_host_bridge *bridge = pci_find_host_bridge(bus);
> struct resource_entry *window;
> @@ -74,8 +74,8 @@ static bool region_contains(struct pci_bus_region *region1,
> return region1->start <= region2->start && region1->end >= region2->end;
> }
>
> -void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res,
> - struct pci_bus_region *region)
> +void __weak pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res,
> + struct pci_bus_region *region)
> {
> struct pci_host_bridge *bridge = pci_find_host_bridge(bus);
> struct resource_entry *window;
> --
> 2.43.0
>
On Tue, 24 Mar 2026, Bjorn Helgaas wrote:
> [+cc Ilpo just for awareness; I assume there's nothing Linux can
> actually *do* with s390 PCI resources?]
I'm somewhat aware they've this speciality (and besides that, I'm
waiting for this change in order to proceed with the series to detect
which resources are properly setup when we enumerate them which got
reverted earlier).
An additional thought related to this, there's IORESOURCE_PCI_FIXED
results in skipping most of the resource fitting and assignment code, so
if nothing really should touch these resources, perhaps that flag might be
of some help.
--
i.
> On Mon, Mar 16, 2026 at 12:15:37PM -0700, Farhan Ali wrote:
> > On s390 today we overwrite the PCI BAR resource address to either an
> > artificial cookie address or MIO address. However this address is different
> > from the bus address of the BARs programmed by firmware. The artificial
> > cookie address was created to index into an array of function handles
> > (zpci_iomap_start). The MIO (mapped I/O) addresses are provided by firmware
> > but maybe different from the bus addresses. This creates an issue when
> > trying to convert the BAR resource address to bus address using the generic
> > pcibios_resource_to_bus().
> >
> > Implement an architecture specific pcibios_resource_to_bus() function to
> > correctly translate PCI BAR resource addresses to bus addresses for s390.
> > Similarly add architecture specific pcibios_bus_to_resource function to do
> > the reverse translation.
>
> 1) It's not clear to me *why* we need these arch-specific versions.
> We went to a lot of trouble to make these interfaces generic, and I'll
> be really sad if they have to be arch-specific again. I don't see any
> direct uses of these in the series. In any case, some reference to
> the user and the actual problem this solves would help.
>
> 2) I'm kind of concerned that the "unusual" s390 PCI resources will be
> unintelligible to people who are used to reading lspci or dmesg logs
> from non-s390 systems, and they might confuse the PCI core resource
> assignment code. I guess there's not really a concept of a PCI host
> bridge on s390, there's no bus hierarchy, and no visible PCI-to-PCI
> bridges, so no windows? Can you use PCIe switches at all?
>
> 3) Maybe this patch should be reordered to be closer to the patch that
> needs these? I don't think it's related to the "PCI: Avoid saving
> config space state if inaccessible" and PCI: Add additional checks for
> flr reset" patches.
>
> > Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
> > Signed-off-by: Farhan Ali <alifm@linux.ibm.com>
> > ---
> > arch/s390/pci/pci.c | 74 +++++++++++++++++++++++++++++++++++++++
> > drivers/pci/host-bridge.c | 8 ++---
> > 2 files changed, 78 insertions(+), 4 deletions(-)
> >
> > diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
> > index 2a430722cbe4..87077e510266 100644
> > --- a/arch/s390/pci/pci.c
> > +++ b/arch/s390/pci/pci.c
> > @@ -272,6 +272,80 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
> > return 0;
> > }
> >
> > +void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,
> > + struct resource *res)
> > +{
> > + struct zpci_bus *zbus = bus->sysdata;
> > + struct zpci_bar_struct *zbar;
> > + struct zpci_dev *zdev;
> > +
> > + region->start = res->start;
> > + region->end = res->end;
> > +
> > + for (int i = 0; i < ZPCI_FUNCTIONS_PER_BUS; i++) {
> > + int j = 0;
> > +
> > + zbar = NULL;
> > + zdev = zbus->function[i];
> > + if (!zdev)
> > + continue;
> > +
> > + for (j = 0; j < PCI_STD_NUM_BARS; j++) {
> > + if (zdev->bars[j].res->start == res->start &&
> > + zdev->bars[j].res->end == res->end &&
> > + res->flags & IORESOURCE_MEM) {
> > + zbar = &zdev->bars[j];
> > + break;
> > + }
> > + }
> > +
> > + if (zbar) {
> > + /* only MMIO is supported */
> > + region->start = zbar->val & PCI_BASE_ADDRESS_MEM_MASK;
> > + if (zbar->val & PCI_BASE_ADDRESS_MEM_TYPE_64)
> > + region->start |= (u64)zdev->bars[j + 1].val << 32;
> > +
> > + region->end = region->start + (1UL << zbar->size) - 1;
> > + return;
> > + }
> > + }
> > +}
> > +
> > +void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res,
> > + struct pci_bus_region *region)
> > +{
> > + struct zpci_bus *zbus = bus->sysdata;
> > + struct zpci_dev *zdev;
> > + resource_size_t start, end;
> > +
> > + res->start = region->start;
> > + res->end = region->end;
> > +
> > + for (int i = 0; i < ZPCI_FUNCTIONS_PER_BUS; i++) {
> > + zdev = zbus->function[i];
> > + if (!zdev || !zdev->has_resources)
> > + continue;
> > +
> > + for (int j = 0; j < PCI_STD_NUM_BARS; j++) {
> > + if (!zdev->bars[j].size)
> > + continue;
> > +
> > + /* only MMIO is supported */
> > + start = zdev->bars[j].val & PCI_BASE_ADDRESS_MEM_MASK;
> > + if (zdev->bars[j].val & PCI_BASE_ADDRESS_MEM_TYPE_64)
> > + start |= (u64)zdev->bars[j + 1].val << 32;
> > +
> > + end = start + (1UL << zdev->bars[j].size) - 1;
> > +
> > + if (start == region->start && end == region->end) {
> > + res->start = zdev->bars[j].res->start;
> > + res->end = zdev->bars[j].res->end;
> > + return;
> > + }
> > + }
> > + }
> > +}
> > +
> > void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size,
> > pgprot_t prot)
> > {
> > diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c
> > index be5ef6516cff..aed031b8a9f3 100644
> > --- a/drivers/pci/host-bridge.c
> > +++ b/drivers/pci/host-bridge.c
> > @@ -49,8 +49,8 @@ void pci_set_host_bridge_release(struct pci_host_bridge *bridge,
> > }
> > EXPORT_SYMBOL_GPL(pci_set_host_bridge_release);
> >
> > -void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,
> > - struct resource *res)
> > +void __weak pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,
> > + struct resource *res)
> > {
> > struct pci_host_bridge *bridge = pci_find_host_bridge(bus);
> > struct resource_entry *window;
> > @@ -74,8 +74,8 @@ static bool region_contains(struct pci_bus_region *region1,
> > return region1->start <= region2->start && region1->end >= region2->end;
> > }
> >
> > -void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res,
> > - struct pci_bus_region *region)
> > +void __weak pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res,
> > + struct pci_bus_region *region)
> > {
> > struct pci_host_bridge *bridge = pci_find_host_bridge(bus);
> > struct resource_entry *window;
> > --
> > 2.43.0
> >
>
On 3/25/2026 4:58 AM, Ilpo Järvinen wrote: > On Tue, 24 Mar 2026, Bjorn Helgaas wrote: > >> [+cc Ilpo just for awareness; I assume there's nothing Linux can >> actually *do* with s390 PCI resources?] > I'm somewhat aware they've this speciality (and besides that, I'm > waiting for this change in order to proceed with the series to detect > which resources are properly setup when we enumerate them which got > reverted earlier). > > An additional thought related to this, there's IORESOURCE_PCI_FIXED > results in skipping most of the resource fitting and assignment code, so > if nothing really should touch these resources, perhaps that flag might be > of some help. I need to look into IORESOURCE_PCI_FIXED. Looking at briefly I think it may work for pci_restore_bars(), though need to check other callers of pcibios_resource_to_bus() to see if they will overwrite the BARs. But for now will remove this patch as part of this series and send it out as a separate patch. Thanks Farhan >
On 3/24/2026 4:06 PM, Bjorn Helgaas wrote:
> [+cc Ilpo just for awareness; I assume there's nothing Linux can
> actually *do* with s390 PCI resources?]
>
> On Mon, Mar 16, 2026 at 12:15:37PM -0700, Farhan Ali wrote:
>> On s390 today we overwrite the PCI BAR resource address to either an
>> artificial cookie address or MIO address. However this address is different
>> from the bus address of the BARs programmed by firmware. The artificial
>> cookie address was created to index into an array of function handles
>> (zpci_iomap_start). The MIO (mapped I/O) addresses are provided by firmware
>> but maybe different from the bus addresses. This creates an issue when
>> trying to convert the BAR resource address to bus address using the generic
>> pcibios_resource_to_bus().
>>
>> Implement an architecture specific pcibios_resource_to_bus() function to
>> correctly translate PCI BAR resource addresses to bus addresses for s390.
>> Similarly add architecture specific pcibios_bus_to_resource function to do
>> the reverse translation.
> 1) It's not clear to me *why* we need these arch-specific versions.
> We went to a lot of trouble to make these interfaces generic, and I'll
> be really sad if they have to be arch-specific again. I don't see any
> direct uses of these in the series. In any case, some reference to
> the user and the actual problem this solves would help.
I came across this issue when in one of the previous version of this
series I was using pci_restore_bars() which calls pci_resource_to_bus()
to get the bus address. Given how we were updating the resource address
in s390, we were programming the BARs with invalid addresses. I also
think a patch from Ilpo, which was later reverted, also exposed this
issue [1]
[1]
https://lore.kernel.org/all/62669f67-d53e-2b56-af8c-e02cdff480a8@linux.intel.com/
>
> 2) I'm kind of concerned that the "unusual" s390 PCI resources will be
> unintelligible to people who are used to reading lspci or dmesg logs
> from non-s390 systems, and they might confuse the PCI core resource
> assignment code. I guess there's not really a concept of a PCI host
> bridge on s390, there's no bus hierarchy, and no visible PCI-to-PCI
> bridges, so no windows? Can you use PCIe switches at all?
On the host kernel we don't expose any of the information such as bus
hierarchy, topology etc. This is all handled by firmware including the
use PCIe switches. Host kernel interfaces with firmware through a set of
instructions. As somewhat alluded to in patch 1, firmware exposes
individual PCI functions to the host. So the host kernel has no idea
about actual topology.
>
> 3) Maybe this patch should be reordered to be closer to the patch that
> needs these? I don't think it's related to the "PCI: Avoid saving
> config space state if inaccessible" and PCI: Add additional checks for
> flr reset" patches.
Currently this patch is not needed by this series. It just fixes a gap
on s390 on how we handle the resources, I could remove this patch from
the series and have it as a separate patch.
Thanks
Farhan
>
>> Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
>> Signed-off-by: Farhan Ali <alifm@linux.ibm.com>
>> ---
>> arch/s390/pci/pci.c | 74 +++++++++++++++++++++++++++++++++++++++
>> drivers/pci/host-bridge.c | 8 ++---
>> 2 files changed, 78 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
>> index 2a430722cbe4..87077e510266 100644
>> --- a/arch/s390/pci/pci.c
>> +++ b/arch/s390/pci/pci.c
>> @@ -272,6 +272,80 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
>> return 0;
>> }
>>
>> +void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,
>> + struct resource *res)
>> +{
>> + struct zpci_bus *zbus = bus->sysdata;
>> + struct zpci_bar_struct *zbar;
>> + struct zpci_dev *zdev;
>> +
>> + region->start = res->start;
>> + region->end = res->end;
>> +
>> + for (int i = 0; i < ZPCI_FUNCTIONS_PER_BUS; i++) {
>> + int j = 0;
>> +
>> + zbar = NULL;
>> + zdev = zbus->function[i];
>> + if (!zdev)
>> + continue;
>> +
>> + for (j = 0; j < PCI_STD_NUM_BARS; j++) {
>> + if (zdev->bars[j].res->start == res->start &&
>> + zdev->bars[j].res->end == res->end &&
>> + res->flags & IORESOURCE_MEM) {
>> + zbar = &zdev->bars[j];
>> + break;
>> + }
>> + }
>> +
>> + if (zbar) {
>> + /* only MMIO is supported */
>> + region->start = zbar->val & PCI_BASE_ADDRESS_MEM_MASK;
>> + if (zbar->val & PCI_BASE_ADDRESS_MEM_TYPE_64)
>> + region->start |= (u64)zdev->bars[j + 1].val << 32;
>> +
>> + region->end = region->start + (1UL << zbar->size) - 1;
>> + return;
>> + }
>> + }
>> +}
>> +
>> +void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res,
>> + struct pci_bus_region *region)
>> +{
>> + struct zpci_bus *zbus = bus->sysdata;
>> + struct zpci_dev *zdev;
>> + resource_size_t start, end;
>> +
>> + res->start = region->start;
>> + res->end = region->end;
>> +
>> + for (int i = 0; i < ZPCI_FUNCTIONS_PER_BUS; i++) {
>> + zdev = zbus->function[i];
>> + if (!zdev || !zdev->has_resources)
>> + continue;
>> +
>> + for (int j = 0; j < PCI_STD_NUM_BARS; j++) {
>> + if (!zdev->bars[j].size)
>> + continue;
>> +
>> + /* only MMIO is supported */
>> + start = zdev->bars[j].val & PCI_BASE_ADDRESS_MEM_MASK;
>> + if (zdev->bars[j].val & PCI_BASE_ADDRESS_MEM_TYPE_64)
>> + start |= (u64)zdev->bars[j + 1].val << 32;
>> +
>> + end = start + (1UL << zdev->bars[j].size) - 1;
>> +
>> + if (start == region->start && end == region->end) {
>> + res->start = zdev->bars[j].res->start;
>> + res->end = zdev->bars[j].res->end;
>> + return;
>> + }
>> + }
>> + }
>> +}
>> +
>> void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size,
>> pgprot_t prot)
>> {
>> diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c
>> index be5ef6516cff..aed031b8a9f3 100644
>> --- a/drivers/pci/host-bridge.c
>> +++ b/drivers/pci/host-bridge.c
>> @@ -49,8 +49,8 @@ void pci_set_host_bridge_release(struct pci_host_bridge *bridge,
>> }
>> EXPORT_SYMBOL_GPL(pci_set_host_bridge_release);
>>
>> -void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,
>> - struct resource *res)
>> +void __weak pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,
>> + struct resource *res)
>> {
>> struct pci_host_bridge *bridge = pci_find_host_bridge(bus);
>> struct resource_entry *window;
>> @@ -74,8 +74,8 @@ static bool region_contains(struct pci_bus_region *region1,
>> return region1->start <= region2->start && region1->end >= region2->end;
>> }
>>
>> -void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res,
>> - struct pci_bus_region *region)
>> +void __weak pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res,
>> + struct pci_bus_region *region)
>> {
>> struct pci_host_bridge *bridge = pci_find_host_bridge(bus);
>> struct resource_entry *window;
>> --
>> 2.43.0
>>
© 2016 - 2026 Red Hat, Inc.