Message ID | 20230324120234.313643-2-baolu.lu@linux.intel.com (mailing list archive) |
---|---|
State | Handled Elsewhere |
Headers | show |
Series | iommu/vt-d: Refactor code for non-PRI IOPF | expand |
On 3/24/23 8:02 PM, Lu Baolu wrote: > 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> > Signed-off-by: Lu Baolu<baolu.lu@linux.intel.com> Hi Dave and Fenghua, The following iommu patches depends on this one. Can I route it to Linus through the iommu tree? Best regards, baolu
On 4/2/23 10:49 PM, Baolu Lu wrote: > On 3/24/23 8:02 PM, Lu Baolu wrote: >> 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> >> Signed-off-by: Lu Baolu<baolu.lu@linux.intel.com> > > Hi Dave and Fenghua, > > The following iommu patches depends on this one. Can I route it to > Linus through the iommu tree? Hi Baolu, you'll need an ack from Vinod, who is the dmaengine subsystem maintainer. I have no objections. > > Best regards, > baolu
On 4/4/23 12:57 AM, Dave Jiang wrote: > On 4/2/23 10:49 PM, Baolu Lu wrote: >> On 3/24/23 8:02 PM, Lu Baolu wrote: >>> 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> >>> Signed-off-by: Lu Baolu<baolu.lu@linux.intel.com> >> >> Hi Dave and Fenghua, >> >> The following iommu patches depends on this one. Can I route it to >> Linus through the iommu tree? > > Hi Baolu, you'll need an ack from Vinod, who is the dmaengine subsystem > maintainer. I have no objections. Hi Vinod, Does this work work for you? Best regards, baolu
diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index 640d3048368e..09ef62aa0635 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -516,6 +516,27 @@ static void idxd_disable_system_pasid(struct idxd_device *idxd) idxd->sva = NULL; } +static int idxd_enable_sva(struct pci_dev *pdev) +{ + int ret; + + ret = iommu_dev_enable_feature(&pdev->dev, IOMMU_DEV_FEAT_IOPF); + if (ret) + return ret; + + ret = iommu_dev_enable_feature(&pdev->dev, IOMMU_DEV_FEAT_SVA); + if (ret) + iommu_dev_disable_feature(&pdev->dev, IOMMU_DEV_FEAT_IOPF); + + return ret; +} + +static void idxd_disable_sva(struct pci_dev *pdev) +{ + iommu_dev_disable_feature(&pdev->dev, IOMMU_DEV_FEAT_SVA); + iommu_dev_disable_feature(&pdev->dev, IOMMU_DEV_FEAT_IOPF); +} + static int idxd_probe(struct idxd_device *idxd) { struct pci_dev *pdev = idxd->pdev; @@ -530,7 +551,7 @@ static int idxd_probe(struct idxd_device *idxd) dev_dbg(dev, "IDXD reset complete\n"); if (IS_ENABLED(CONFIG_INTEL_IDXD_SVM) && sva) { - if (iommu_dev_enable_feature(dev, IOMMU_DEV_FEAT_SVA)) { + if (idxd_enable_sva(pdev)) { dev_warn(dev, "Unable to turn on user SVA feature.\n"); } else { set_bit(IDXD_FLAG_USER_PASID_ENABLED, &idxd->flags); @@ -578,21 +599,19 @@ static int idxd_probe(struct idxd_device *idxd) if (device_pasid_enabled(idxd)) idxd_disable_system_pasid(idxd); if (device_user_pasid_enabled(idxd)) - iommu_dev_disable_feature(dev, IOMMU_DEV_FEAT_SVA); + idxd_disable_sva(pdev); return rc; } static void idxd_cleanup(struct idxd_device *idxd) { - struct device *dev = &idxd->pdev->dev; - perfmon_pmu_remove(idxd); idxd_cleanup_interrupts(idxd); idxd_cleanup_internals(idxd); if (device_pasid_enabled(idxd)) idxd_disable_system_pasid(idxd); if (device_user_pasid_enabled(idxd)) - iommu_dev_disable_feature(dev, IOMMU_DEV_FEAT_SVA); + idxd_disable_sva(idxd->pdev); } 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) pci_free_irq_vectors(pdev); pci_iounmap(pdev, idxd->reg_base); if (device_user_pasid_enabled(idxd)) - iommu_dev_disable_feature(&pdev->dev, IOMMU_DEV_FEAT_SVA); + idxd_disable_sva(pdev); pci_disable_device(pdev); destroy_workqueue(idxd->wq); perfmon_pmu_remove(idxd);