Hi,
I came across some issues in PCI code for s390 while working on VFIO error recovery for s390 PCI devices [1]. These patches can be indepedently applied and has no depedency on error recovery patch series. We would like to get these patches merged as they do fix some existing issues.
[1] https://lore.kernel.org/all/20250924171628.826-1-alifm@linux.ibm.com/
Thanks Farhan
Farhan Ali (3): PCI: Allow per function PCI slots s390/pci: Add architecture specific resource/bus address translation s390/pci: Restore IRQ unconditionally for the zPCI device
arch/s390/include/asm/pci.h | 1 - arch/s390/pci/pci.c | 74 ++++++++++++++++++++++++++++++ arch/s390/pci/pci_irq.c | 9 +--- drivers/pci/host-bridge.c | 4 +- drivers/pci/hotplug/s390_pci_hpc.c | 10 +++- drivers/pci/pci.c | 5 +- drivers/pci/slot.c | 14 ++++-- include/linux/pci.h | 1 + 8 files changed, 100 insertions(+), 18 deletions(-)
On s390 systems, which use a machine level hypervisor, PCI devices are always accessed through a form of PCI pass-through which fundamentally operates on a per PCI function granularity. This is also reflected in the s390 PCI hotplug driver which creates hotplug slots for individual PCI functions. Its reset_slot() function, which is a wrapper for zpci_hot_reset_device(), thus also resets individual functions.
Currently, the kernel's PCI_SLOT() macro assigns the same pci_slot object to multifunction devices. This approach worked fine on s390 systems that only exposed virtual functions as individual PCI domains to the operating system. Since commit 44510d6fa0c0 ("s390/pci: Handling multifunctions") s390 supports exposing the topology of multifunction PCI devices by grouping them in a shared PCI domain. When attempting to reset a function through the hotplug driver, the shared slot assignment causes the wrong function to be reset instead of the intended one. It also leaks memory as we do create a pci_slot object for the function, but don't correctly free it in pci_slot_release().
Add a flag for struct pci_slot to allow per function PCI slots for functions managed through a hypervisor, which exposes individual PCI functions while retaining the topology.
Fixes: 44510d6fa0c0 ("s390/pci: Handling multifunctions") Cc: stable@vger.kernel.org Suggested-by: Niklas Schnelle schnelle@linux.ibm.com Reviewed-by: Benjamin Block bblock@linux.ibm.com Signed-off-by: Farhan Ali alifm@linux.ibm.com --- drivers/pci/hotplug/s390_pci_hpc.c | 10 ++++++++-- drivers/pci/pci.c | 5 +++-- drivers/pci/slot.c | 14 +++++++++++--- include/linux/pci.h | 1 + 4 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c index d9996516f49e..8b547de464bf 100644 --- a/drivers/pci/hotplug/s390_pci_hpc.c +++ b/drivers/pci/hotplug/s390_pci_hpc.c @@ -126,14 +126,20 @@ static const struct hotplug_slot_ops s390_hotplug_slot_ops = {
int zpci_init_slot(struct zpci_dev *zdev) { + int ret; char name[SLOT_NAME_SIZE]; struct zpci_bus *zbus = zdev->zbus;
zdev->hotplug_slot.ops = &s390_hotplug_slot_ops;
snprintf(name, SLOT_NAME_SIZE, "%08x", zdev->fid); - return pci_hp_register(&zdev->hotplug_slot, zbus->bus, - zdev->devfn, name); + ret = pci_hp_register(&zdev->hotplug_slot, zbus->bus, + zdev->devfn, name); + if (ret) + return ret; + + zdev->hotplug_slot.pci_slot->per_func_slot = 1; + return 0; }
void zpci_exit_slot(struct zpci_dev *zdev) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index b14dd064006c..36ee38e0d817 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -4980,8 +4980,9 @@ static int pci_reset_hotplug_slot(struct hotplug_slot *hotplug, bool probe)
static int pci_dev_reset_slot_function(struct pci_dev *dev, bool probe) { - if (dev->multifunction || dev->subordinate || !dev->slot || - dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET) + if (dev->subordinate || !dev->slot || + dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET || + (dev->multifunction && !dev->slot->per_func_slot)) return -ENOTTY;
return pci_reset_hotplug_slot(dev->slot->hotplug, probe); diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index 50fb3eb595fe..51ee59e14393 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c @@ -63,6 +63,14 @@ static ssize_t cur_speed_read_file(struct pci_slot *slot, char *buf) return bus_speed_read(slot->bus->cur_bus_speed, buf); }
+static bool pci_dev_matches_slot(struct pci_dev *dev, struct pci_slot *slot) +{ + if (slot->per_func_slot) + return dev->devfn == slot->number; + + return PCI_SLOT(dev->devfn) == slot->number; +} + static void pci_slot_release(struct kobject *kobj) { struct pci_dev *dev; @@ -73,7 +81,7 @@ static void pci_slot_release(struct kobject *kobj)
down_read(&pci_bus_sem); list_for_each_entry(dev, &slot->bus->devices, bus_list) - if (PCI_SLOT(dev->devfn) == slot->number) + if (pci_dev_matches_slot(dev, slot)) dev->slot = NULL; up_read(&pci_bus_sem);
@@ -166,7 +174,7 @@ void pci_dev_assign_slot(struct pci_dev *dev)
mutex_lock(&pci_slot_mutex); list_for_each_entry(slot, &dev->bus->slots, list) - if (PCI_SLOT(dev->devfn) == slot->number) + if (pci_dev_matches_slot(dev, slot)) dev->slot = slot; mutex_unlock(&pci_slot_mutex); } @@ -285,7 +293,7 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
down_read(&pci_bus_sem); list_for_each_entry(dev, &parent->devices, bus_list) - if (PCI_SLOT(dev->devfn) == slot_nr) + if (pci_dev_matches_slot(dev, slot)) dev->slot = slot; up_read(&pci_bus_sem);
diff --git a/include/linux/pci.h b/include/linux/pci.h index d1fdf81fbe1e..6ad194597ab5 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -78,6 +78,7 @@ struct pci_slot { struct list_head list; /* Node in list of slots */ struct hotplug_slot *hotplug; /* Hotplug info (move here) */ unsigned char number; /* PCI_SLOT(pci_dev->devfn) */ + unsigned int per_func_slot:1; /* Allow per function slot */ struct kobject kobj; };
On Mon, 2025-10-20 at 12:01 -0700, Farhan Ali wrote:
On s390 systems, which use a machine level hypervisor, PCI devices are always accessed through a form of PCI pass-through which fundamentally operates on a per PCI function granularity. This is also reflected in the s390 PCI hotplug driver which creates hotplug slots for individual PCI functions. Its reset_slot() function, which is a wrapper for zpci_hot_reset_device(), thus also resets individual functions.
Currently, the kernel's PCI_SLOT() macro assigns the same pci_slot object to multifunction devices. This approach worked fine on s390 systems that only exposed virtual functions as individual PCI domains to the operating system. Since commit 44510d6fa0c0 ("s390/pci: Handling multifunctions") s390 supports exposing the topology of multifunction PCI devices by grouping them in a shared PCI domain. When attempting to reset a function through the hotplug driver, the shared slot assignment causes the wrong function to be reset instead of the intended one. It also leaks memory as we do create a pci_slot object for the function, but don't correctly free it in pci_slot_release().
Add a flag for struct pci_slot to allow per function PCI slots for functions managed through a hypervisor, which exposes individual PCI functions while retaining the topology.
Fixes: 44510d6fa0c0 ("s390/pci: Handling multifunctions") Cc: stable@vger.kernel.org Suggested-by: Niklas Schnelle schnelle@linux.ibm.com Reviewed-by: Benjamin Block bblock@linux.ibm.com Signed-off-by: Farhan Ali alifm@linux.ibm.com
drivers/pci/hotplug/s390_pci_hpc.c | 10 ++++++++-- drivers/pci/pci.c | 5 +++-- drivers/pci/slot.c | 14 +++++++++++--- include/linux/pci.h | 1 + 4 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c index d9996516f49e..8b547de464bf 100644 --- a/drivers/pci/hotplug/s390_pci_hpc.c +++ b/drivers/pci/hotplug/s390_pci_hpc.c @@ -126,14 +126,20 @@ static const struct hotplug_slot_ops s390_hotplug_slot_ops = { int zpci_init_slot(struct zpci_dev *zdev) {
- int ret; char name[SLOT_NAME_SIZE]; struct zpci_bus *zbus = zdev->zbus;
zdev->hotplug_slot.ops = &s390_hotplug_slot_ops; snprintf(name, SLOT_NAME_SIZE, "%08x", zdev->fid);
- return pci_hp_register(&zdev->hotplug_slot, zbus->bus,
zdev->devfn, name);
- ret = pci_hp_register(&zdev->hotplug_slot, zbus->bus,
zdev->devfn, name);- if (ret)
return ret;- zdev->hotplug_slot.pci_slot->per_func_slot = 1;
I think the way this works is a bit odd. Due to the order of setting the flag pci_create_slot() in pci_hp_register() tries to match using the wrong per_func_slot == 0. This doesn't really cause mismatches though because the slot->number won't match the PCI_SLOT(dev->devfn) except for the slot->number 0 where it is fine.
One way to improve(?) on this is to have a per_func_slot flag also in the struct hotplug_slot and then copy it over into the newly created struct pci_slot. But then we have this flag twice. Or maybe this really should be an argument to pci_create_slot()?
On 10/21/2025 5:49 AM, Niklas Schnelle wrote:
On Mon, 2025-10-20 at 12:01 -0700, Farhan Ali wrote:
On s390 systems, which use a machine level hypervisor, PCI devices are always accessed through a form of PCI pass-through which fundamentally operates on a per PCI function granularity. This is also reflected in the s390 PCI hotplug driver which creates hotplug slots for individual PCI functions. Its reset_slot() function, which is a wrapper for zpci_hot_reset_device(), thus also resets individual functions.
Currently, the kernel's PCI_SLOT() macro assigns the same pci_slot object to multifunction devices. This approach worked fine on s390 systems that only exposed virtual functions as individual PCI domains to the operating system. Since commit 44510d6fa0c0 ("s390/pci: Handling multifunctions") s390 supports exposing the topology of multifunction PCI devices by grouping them in a shared PCI domain. When attempting to reset a function through the hotplug driver, the shared slot assignment causes the wrong function to be reset instead of the intended one. It also leaks memory as we do create a pci_slot object for the function, but don't correctly free it in pci_slot_release().
Add a flag for struct pci_slot to allow per function PCI slots for functions managed through a hypervisor, which exposes individual PCI functions while retaining the topology.
Fixes: 44510d6fa0c0 ("s390/pci: Handling multifunctions") Cc: stable@vger.kernel.org Suggested-by: Niklas Schnelle schnelle@linux.ibm.com Reviewed-by: Benjamin Block bblock@linux.ibm.com Signed-off-by: Farhan Ali alifm@linux.ibm.com
drivers/pci/hotplug/s390_pci_hpc.c | 10 ++++++++-- drivers/pci/pci.c | 5 +++-- drivers/pci/slot.c | 14 +++++++++++--- include/linux/pci.h | 1 + 4 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c index d9996516f49e..8b547de464bf 100644 --- a/drivers/pci/hotplug/s390_pci_hpc.c +++ b/drivers/pci/hotplug/s390_pci_hpc.c @@ -126,14 +126,20 @@ static const struct hotplug_slot_ops s390_hotplug_slot_ops = { int zpci_init_slot(struct zpci_dev *zdev) {
- int ret; char name[SLOT_NAME_SIZE]; struct zpci_bus *zbus = zdev->zbus;
zdev->hotplug_slot.ops = &s390_hotplug_slot_ops; snprintf(name, SLOT_NAME_SIZE, "%08x", zdev->fid);
- return pci_hp_register(&zdev->hotplug_slot, zbus->bus,
zdev->devfn, name);
- ret = pci_hp_register(&zdev->hotplug_slot, zbus->bus,
zdev->devfn, name);- if (ret)
return ret;- zdev->hotplug_slot.pci_slot->per_func_slot = 1;
I think the way this works is a bit odd. Due to the order of setting the flag pci_create_slot() in pci_hp_register() tries to match using the wrong per_func_slot == 0. This doesn't really cause mismatches though because the slot->number won't match the PCI_SLOT(dev->devfn) except for the slot->number 0 where it is fine.
One way to improve(?) on this is to have a per_func_slot flag also in the struct hotplug_slot and then copy it over into the newly created struct pci_slot. But then we have this flag twice. Or maybe this really should be an argument to pci_create_slot()?
This would still work as we associate the struct pci_dev to struct pci_slot in pci_dev_assign_slot(), when we would have the flag set. But I do see your point that there is room for improvement here. As discussed offline we can maybe have the flag in struct pci_bus since we already have the slots list. This would allow us to set the flag for zpci devices at the creation of the pci_bus. And can be used by pci_create_slot() and pci_dev_assign_slot() to correctly set the slot for the pci dev. Will post a v2 with this.
Thanks
Farhan
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 address. 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 | 4 +-- 2 files changed, 76 insertions(+), 2 deletions(-)
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index c82c577db2bc..cacad02b2b7f 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -264,6 +264,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 afa50b446567..56d62afb3afe 100644 --- a/drivers/pci/host-bridge.c +++ b/drivers/pci/host-bridge.c @@ -48,7 +48,7 @@ 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, +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); @@ -73,7 +73,7 @@ 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, +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);
Hi,
Thanks for your patch.
FYI: kernel test robot notices the stable kernel rule is not satisfied.
The check is based on https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html#opti...
Rule: add the tag "Cc: stable@vger.kernel.org" in the sign-off area to have the patch automatically included in the stable tree. Subject: [PATCH v1 2/3] s390/pci: Add architecture specific resource/bus address translation Link: https://lore.kernel.org/stable/20251020190200.1365-3-alifm%40linux.ibm.com
Commit c1e18c17bda6 ("s390/pci: add zpci_set_irq()/zpci_clear_irq()"), introduced the zpci_set_irq() and zpci_clear_irq(), to be used while resetting a zPCI device.
Commit da995d538d3a ("s390/pci: implement reset_slot for hotplug slot"), mentions zpci_clear_irq() being called in the path for zpci_hot_reset_device(). But that is not the case anymore and these functions are not called outside of this file. Instead zpci_hot_reset_device() relies on zpci_disable_device() also clearing the IRQs, but misses to reset the zdev->irqs_registered flag.
However after a CLP disable/enable reset, the device's IRQ are unregistered, but the flag zdev->irq_registered does not get cleared. It creates an inconsistent state and so arch_restore_msi_irqs() doesn't correctly restore the device's IRQ. This becomes a problem when a PCI driver tries to restore the state of the device through pci_restore_state(). Restore IRQ unconditionally for the device and remove the irq_registered flag as its redundant.
Reviewed-by: Niklas Schnelle schnelle@linux.ibm.com Signed-off-by: Farhan Ali alifm@linux.ibm.com --- arch/s390/include/asm/pci.h | 1 - arch/s390/pci/pci_irq.c | 9 +-------- 2 files changed, 1 insertion(+), 9 deletions(-)
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h index 6890925d5587..a32f465ecf73 100644 --- a/arch/s390/include/asm/pci.h +++ b/arch/s390/include/asm/pci.h @@ -145,7 +145,6 @@ struct zpci_dev { u8 has_resources : 1; u8 is_physfn : 1; u8 util_str_avail : 1; - u8 irqs_registered : 1; u8 tid_avail : 1; u8 rtr_avail : 1; /* Relaxed translation allowed */ unsigned int devfn; /* DEVFN part of the RID*/ diff --git a/arch/s390/pci/pci_irq.c b/arch/s390/pci/pci_irq.c index 84482a921332..e73be96ce5fe 100644 --- a/arch/s390/pci/pci_irq.c +++ b/arch/s390/pci/pci_irq.c @@ -107,9 +107,6 @@ static int zpci_set_irq(struct zpci_dev *zdev) else rc = zpci_set_airq(zdev);
- if (!rc) - zdev->irqs_registered = 1; - return rc; }
@@ -123,9 +120,6 @@ static int zpci_clear_irq(struct zpci_dev *zdev) else rc = zpci_clear_airq(zdev);
- if (!rc) - zdev->irqs_registered = 0; - return rc; }
@@ -427,8 +421,7 @@ bool arch_restore_msi_irqs(struct pci_dev *pdev) { struct zpci_dev *zdev = to_zpci(pdev);
- if (!zdev->irqs_registered) - zpci_set_irq(zdev); + zpci_set_irq(zdev); return true; }
On 10/20/25 3:02 PM, Farhan Ali wrote:
Commit c1e18c17bda6 ("s390/pci: add zpci_set_irq()/zpci_clear_irq()"), introduced the zpci_set_irq() and zpci_clear_irq(), to be used while resetting a zPCI device.
Commit da995d538d3a ("s390/pci: implement reset_slot for hotplug slot"), mentions zpci_clear_irq() being called in the path for zpci_hot_reset_device(). But that is not the case anymore and these functions are not called outside of this file. Instead zpci_hot_reset_device() relies on zpci_disable_device() also clearing the IRQs, but misses to reset the zdev->irqs_registered flag.
However after a CLP disable/enable reset, the device's IRQ are unregistered, but the flag zdev->irq_registered does not get cleared. It creates an inconsistent state and so arch_restore_msi_irqs() doesn't correctly restore the device's IRQ. This becomes a problem when a PCI driver tries to restore the state of the device through pci_restore_state(). Restore IRQ unconditionally for the device and remove the irq_registered flag as its redundant.
Reviewed-by: Niklas Schnelle schnelle@linux.ibm.com Signed-off-by: Farhan Ali alifm@linux.ibm.com
Reviewed-by: Matthew Rosato mjrosato@linux.ibm.com
But one question: Unlike the other 2 patches in this series, this only touches s390 code. It doesn't depend on the other 2 patches in this series, right?
If not then shouldn't this one go thru s390 rather than PCI subsystem? Note: none of the s390 arch maintainers are on CC.
arch/s390/include/asm/pci.h | 1 - arch/s390/pci/pci_irq.c | 9 +-------- 2 files changed, 1 insertion(+), 9 deletions(-)
On 10/21/2025 7:07 AM, Matthew Rosato wrote:
On 10/20/25 3:02 PM, Farhan Ali wrote:
Commit c1e18c17bda6 ("s390/pci: add zpci_set_irq()/zpci_clear_irq()"), introduced the zpci_set_irq() and zpci_clear_irq(), to be used while resetting a zPCI device.
Commit da995d538d3a ("s390/pci: implement reset_slot for hotplug slot"), mentions zpci_clear_irq() being called in the path for zpci_hot_reset_device(). But that is not the case anymore and these functions are not called outside of this file. Instead zpci_hot_reset_device() relies on zpci_disable_device() also clearing the IRQs, but misses to reset the zdev->irqs_registered flag.
However after a CLP disable/enable reset, the device's IRQ are unregistered, but the flag zdev->irq_registered does not get cleared. It creates an inconsistent state and so arch_restore_msi_irqs() doesn't correctly restore the device's IRQ. This becomes a problem when a PCI driver tries to restore the state of the device through pci_restore_state(). Restore IRQ unconditionally for the device and remove the irq_registered flag as its redundant.
Reviewed-by: Niklas Schnelle schnelle@linux.ibm.com Signed-off-by: Farhan Ali alifm@linux.ibm.com
Reviewed-by: Matthew Rosato mjrosato@linux.ibm.com
But one question: Unlike the other 2 patches in this series, this only touches s390 code. It doesn't depend on the other 2 patches in this series, right?
If not then shouldn't this one go thru s390 rather than PCI subsystem? Note: none of the s390 arch maintainers are on CC.
Yes I think this could go through s390 tree as it just changes s390/pci code. Will submit this as a separate patch from this series.
Thanks
Farhan
arch/s390/include/asm/pci.h | 1 - arch/s390/pci/pci_irq.c | 9 +-------- 2 files changed, 1 insertion(+), 9 deletions(-)
linux-stable-mirror@lists.linaro.org