]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
s390/pci: Restore IRQ unconditionally for the zPCI device
authorFarhan Ali <alifm@linux.ibm.com>
Wed, 22 Oct 2025 16:47:26 +0000 (09:47 -0700)
committerHeiko Carstens <hca@linux.ibm.com>
Fri, 24 Oct 2025 13:25:43 +0000 (15:25 +0200)
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.

Fixes: c1e18c17bda6 ("s390/pci: add zpci_set_irq()/zpci_clear_irq()")
Cc: stable@vger.kernnel.org
Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Farhan Ali <alifm@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
arch/s390/include/asm/pci.h
arch/s390/pci/pci_irq.c

index 6890925d5587b1825cc51ac7e2be2003132244da..a32f465ecf73a5cc3408a312d94ec888d62848cc 100644 (file)
@@ -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*/
index 84482a92133220f446e30ae61b6af196aa17b4b4..e73be96ce5fe6473fc193d65b8f0ff635d6a98ba 100644 (file)
@@ -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;
 }