Skip to content

Commit 84c9ef7

Browse files
LuBaolujoergroedel
authored andcommitted
dmaengine: idxd: Add enable/disable device IOPF feature
The iommu subsystem requires IOMMU_DEV_FEAT_IOPF must be enabled before and disabled after IOMMU_DEV_FEAT_SVA, if device's I/O page faults rely on the IOMMU. Add explicit IOMMU_DEV_FEAT_IOPF enabling/disabling in this driver. At present, missing IOPF enabling/disabling doesn't cause any real issue, because the IOMMU driver places the IOPF enabling/disabling in the path of SVA feature handling. But this may change. Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Fenghua Yu <fenghua.yu@intel.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Acked-by: Vinod Koul <vkoul@kernel.org> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Link: https://lore.kernel.org/r/20230324120234.313643-2-baolu.lu@linux.intel.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
1 parent e8d018d commit 84c9ef7

1 file changed

Lines changed: 25 additions & 6 deletions

File tree

drivers/dma/idxd/init.c

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,27 @@ static void idxd_disable_system_pasid(struct idxd_device *idxd)
516516
idxd->sva = NULL;
517517
}
518518

519+
static int idxd_enable_sva(struct pci_dev *pdev)
520+
{
521+
int ret;
522+
523+
ret = iommu_dev_enable_feature(&pdev->dev, IOMMU_DEV_FEAT_IOPF);
524+
if (ret)
525+
return ret;
526+
527+
ret = iommu_dev_enable_feature(&pdev->dev, IOMMU_DEV_FEAT_SVA);
528+
if (ret)
529+
iommu_dev_disable_feature(&pdev->dev, IOMMU_DEV_FEAT_IOPF);
530+
531+
return ret;
532+
}
533+
534+
static void idxd_disable_sva(struct pci_dev *pdev)
535+
{
536+
iommu_dev_disable_feature(&pdev->dev, IOMMU_DEV_FEAT_SVA);
537+
iommu_dev_disable_feature(&pdev->dev, IOMMU_DEV_FEAT_IOPF);
538+
}
539+
519540
static int idxd_probe(struct idxd_device *idxd)
520541
{
521542
struct pci_dev *pdev = idxd->pdev;
@@ -530,7 +551,7 @@ static int idxd_probe(struct idxd_device *idxd)
530551
dev_dbg(dev, "IDXD reset complete\n");
531552

532553
if (IS_ENABLED(CONFIG_INTEL_IDXD_SVM) && sva) {
533-
if (iommu_dev_enable_feature(dev, IOMMU_DEV_FEAT_SVA)) {
554+
if (idxd_enable_sva(pdev)) {
534555
dev_warn(dev, "Unable to turn on user SVA feature.\n");
535556
} else {
536557
set_bit(IDXD_FLAG_USER_PASID_ENABLED, &idxd->flags);
@@ -578,21 +599,19 @@ static int idxd_probe(struct idxd_device *idxd)
578599
if (device_pasid_enabled(idxd))
579600
idxd_disable_system_pasid(idxd);
580601
if (device_user_pasid_enabled(idxd))
581-
iommu_dev_disable_feature(dev, IOMMU_DEV_FEAT_SVA);
602+
idxd_disable_sva(pdev);
582603
return rc;
583604
}
584605

585606
static void idxd_cleanup(struct idxd_device *idxd)
586607
{
587-
struct device *dev = &idxd->pdev->dev;
588-
589608
perfmon_pmu_remove(idxd);
590609
idxd_cleanup_interrupts(idxd);
591610
idxd_cleanup_internals(idxd);
592611
if (device_pasid_enabled(idxd))
593612
idxd_disable_system_pasid(idxd);
594613
if (device_user_pasid_enabled(idxd))
595-
iommu_dev_disable_feature(dev, IOMMU_DEV_FEAT_SVA);
614+
idxd_disable_sva(idxd->pdev);
596615
}
597616

598617
static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -710,7 +729,7 @@ static void idxd_remove(struct pci_dev *pdev)
710729
pci_free_irq_vectors(pdev);
711730
pci_iounmap(pdev, idxd->reg_base);
712731
if (device_user_pasid_enabled(idxd))
713-
iommu_dev_disable_feature(&pdev->dev, IOMMU_DEV_FEAT_SVA);
732+
idxd_disable_sva(pdev);
714733
pci_disable_device(pdev);
715734
destroy_workqueue(idxd->wq);
716735
perfmon_pmu_remove(idxd);

0 commit comments

Comments
 (0)