Ensure that fmb_lock is held by pcibios_enable_device() and pcibios_disable_device() when calling zpci_fmb_enable_device() or zpci_fmb_disable_device(), respectively. Additionally, assert that the fmb_lock is held within the latter two functions to prevent future race conditions regarding new callers. Fixes: af0a8a8453f7 ("s390/pci: implement pcibios_add_device") Fixes: 944239c59e93 ("s390/pci: implement pcibios_release_device") Cc: stable@vger.kernel.org Signed-off-by: Omar Elghoul --- arch/s390/pci/pci.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 39bd2adfc240..2910d4038d39 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -173,6 +173,8 @@ int zpci_fmb_enable_device(struct zpci_dev *zdev) unsigned long flags; u8 cc, status; + lockdep_assert_held(&zdev->fmb_lock); + if (zdev->fmb || sizeof(*zdev->fmb) < zdev->fmb_length) return -EINVAL; @@ -211,6 +213,8 @@ int zpci_fmb_disable_device(struct zpci_dev *zdev) struct zpci_fib fib = {0}; u8 cc, status; + lockdep_assert_held(&zdev->fmb_lock); + if (!zdev->fmb) return -EINVAL; @@ -639,7 +643,9 @@ int pcibios_enable_device(struct pci_dev *pdev, int mask) struct zpci_dev *zdev = to_zpci(pdev); zpci_debug_init_device(zdev, dev_name(&pdev->dev)); + mutex_lock(&zdev->fmb_lock); zpci_fmb_enable_device(zdev); + mutex_unlock(&zdev->fmb_lock); return pci_enable_resources(pdev, mask); } @@ -648,7 +654,9 @@ void pcibios_disable_device(struct pci_dev *pdev) { struct zpci_dev *zdev = to_zpci(pdev); + mutex_lock(&zdev->fmb_lock); zpci_fmb_disable_device(zdev); + mutex_unlock(&zdev->fmb_lock); zpci_debug_exit_device(zdev); } -- 2.54.0