From: Joerg Roedel <jroedel@xxxxxxx> The use of the SR-IOV lock for ATS causes a dead-lock in the AMD-IOMMU driver when virtual functions are added that have an ATS capability. The problem is that the VFs will be added to the bus with the SR-IOV lock held. While added to the bus the device-notifiers will run and invoke AMD IOMMU code, which itself will assign the device to a domain try to enable ATS. When it calls pci_enable_ats() this will dead-lock. Fix this by introducing a global ats_lock. ATS enablement and disablement isn't in any fast-path, so a global lock shouldn't hurt here. Cc: stable@xxxxxxxxxx Reported-by: Gregor Dick <gdick@xxxxxxxxxxxxxx> Signed-off-by: Joerg Roedel <jroedel@xxxxxxx> --- drivers/pci/ats.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c index a8099d4..f0c3c6f 100644 --- a/drivers/pci/ats.c +++ b/drivers/pci/ats.c @@ -17,6 +17,8 @@ #include "pci.h" +static DEFINE_MUTEX(ats_lock); + static int ats_alloc_one(struct pci_dev *dev, int ps) { int pos; @@ -67,7 +69,7 @@ int pci_enable_ats(struct pci_dev *dev, int ps) if (dev->is_physfn || dev->is_virtfn) { struct pci_dev *pdev = dev->is_physfn ? dev : dev->physfn; - mutex_lock(&pdev->sriov->lock); + mutex_lock(&ats_lock); if (pdev->ats) rc = pdev->ats->stu == ps ? 0 : -EINVAL; else @@ -75,7 +77,7 @@ int pci_enable_ats(struct pci_dev *dev, int ps) if (!rc) pdev->ats->ref_cnt++; - mutex_unlock(&pdev->sriov->lock); + mutex_unlock(&ats_lock); if (rc) return rc; } @@ -116,11 +118,11 @@ void pci_disable_ats(struct pci_dev *dev) if (dev->is_physfn || dev->is_virtfn) { struct pci_dev *pdev = dev->is_physfn ? dev : dev->physfn; - mutex_lock(&pdev->sriov->lock); + mutex_lock(&ats_lock); pdev->ats->ref_cnt--; if (!pdev->ats->ref_cnt) ats_free_one(pdev); - mutex_unlock(&pdev->sriov->lock); + mutex_unlock(&ats_lock); } if (!dev->is_physfn) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html