[PATCH v3 4/5] iommu/amd: Fail probe on ATS configuration failure
Pranjal Shrivastava <[email protected]>
| Newsgroups | dev.linux.lists.iommu,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pci |
|---|---|
| Message-ID | <[email protected]> |
Update the driver to call pci_prepare_ats() after checking if pci_ats_supported() and fail the probe_device if pci_prepare_ats() returns an error. Additionally, update pdev_enable_cap_ats() to WARN_ON() a failure in pci_enable_ats(). Reviewed-by: Vasant Hegde <[email protected]> Signed-off-by: Pranjal Shrivastava <[email protected]> --- drivers/iommu/amd/iommu.c | 40 +++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index ed336bca1a2e..ecee4d097e4e 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -573,10 +573,17 @@ static inline int pdev_enable_cap_ats(struct pci_dev *pdev) if (amd_iommu_iotlb_sup && (dev_data->flags & AMD_IOMMU_DEVICE_FLAG_ATS_SUP)) { ret = pci_enable_ats(pdev, PAGE_SHIFT); - if (!ret) { - dev_data->ats_enabled = 1; - dev_data->ats_qdep = pci_ats_queue_depth(pdev); - } + + /* + * pci_enable_ats() should not fail here because earlier + * checks have already verified support & config. + */ + if (WARN_ON(ret)) + return ret; + + dev_data->ats_enabled = 1; + dev_data->ats_qdep = pci_ats_queue_depth(pdev); + ret = 0; } return ret; @@ -2483,10 +2490,12 @@ static void detach_device(struct device *dev) mutex_unlock(&dev_data->mutex); } -static void iommu_init_device_caps(struct iommu_dev_data *dev_data, - struct device *dev, - struct amd_iommu *iommu) +static int iommu_init_device_caps(struct iommu_dev_data *dev_data, + struct device *dev, + struct amd_iommu *iommu) { + int ret; + if (FEATURE_NUM_INT_REMAP_SUP_2K(amd_iommu_efr2)) dev_data->max_irqs = MAX_IRQS_PER_TABLE_2K; else @@ -2495,7 +2504,7 @@ static void iommu_init_device_caps(struct iommu_dev_data *dev_data, amd_iommu_set_pci_msi_domain(dev, iommu); if (!dev_is_pci(dev)) - return; + return 0; /* * By default we use passthrough mode for IOMMUv2 capable device. @@ -2518,7 +2527,13 @@ static void iommu_init_device_caps(struct iommu_dev_data *dev_data, pci_max_pasids(to_pci_dev(dev))); } - pci_prepare_ats(to_pci_dev(dev), PAGE_SHIFT); + if (pci_ats_supported(to_pci_dev(dev))) { + ret = pci_prepare_ats(to_pci_dev(dev), PAGE_SHIFT); + if (ret) + return ret; + } + + return 0; } static struct iommu_device *amd_iommu_probe_device(struct device *dev) @@ -2543,7 +2558,12 @@ static struct iommu_device *amd_iommu_probe_device(struct device *dev) goto err_deinit; } - iommu_init_device_caps(dev_data, dev, iommu); + ret = iommu_init_device_caps(dev_data, dev, iommu); + if (ret) { + iommu_dev = ERR_PTR(ret); + goto out_err; + } + iommu_dev = &iommu->iommu; /* -- 2.55.0.766.g2966f0265a-goog