From: Jacob Pan <jacob.jun.pan@linux.intel.com>
To: iommu@lists.linux-foundation.org,
LKML <linux-kernel@vger.kernel.org>,
Joerg Roedel <joro@8bytes.org>, Jason Gunthorpe <jgg@nvidia.com>,
"Christoph Hellwig" <hch@infradead.org>
Cc: "Lu Baolu" <baolu.lu@linux.intel.com>,
Raj Ashok <ashok.raj@intel.com>,
"Kumar, Sanjay K" <sanjay.k.kumar@intel.com>,
Dave Jiang <dave.jiang@intel.com>,
Tony Luck <tony.luck@intel.com>,
mike.campin@intel.com, Yi Liu <yi.l.liu@intel.com>,
"Tian, Kevin" <kevin.tian@intel.com>
Subject: [RFC 3/7] iommu/vt-d: Add DMA w/ PASID support for PA and IOVA
Date: Tue, 21 Sep 2021 13:29:37 -0700 [thread overview]
Message-ID: <1632256181-36071-4-git-send-email-jacob.jun.pan@linux.intel.com> (raw)
In-Reply-To: <1632256181-36071-1-git-send-email-jacob.jun.pan@linux.intel.com>
For physical address(PA) mode, PASID entry for the given supervisor
PASID will be set up for HW pass-through (PT). For IOVA mode, the
supervisor PASID entry will be configured the same as PASID 0, which is
a special PASID for DMA request w/o PASID, a.k.a.
RID2PASID. Additional IOTLB flush for the supervisor PASID is also
included.
Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com>
---
drivers/iommu/intel/iommu.c | 95 ++++++++++++++++++++++++++++++++++++-
include/linux/intel-iommu.h | 7 ++-
2 files changed, 100 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index be35284a2016..cbcfd178c16f 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -1631,7 +1631,11 @@ static void domain_flush_piotlb(struct intel_iommu *iommu,
if (domain->default_pasid)
qi_flush_piotlb(iommu, did, domain->default_pasid,
addr, npages, ih);
-
+ if (domain->s_pasid) {
+ pr_alert_ratelimited("%s: pasid %u", __func__, domain->s_pasid);
+ qi_flush_piotlb(iommu, did, domain->s_pasid,
+ addr, npages, ih);
+ }
if (!list_empty(&domain->devices))
qi_flush_piotlb(iommu, did, PASID_RID2PASID, addr, npages, ih);
}
@@ -5535,6 +5539,93 @@ static void intel_iommu_iotlb_sync_map(struct iommu_domain *domain,
}
}
+static int intel_enable_pasid_dma(struct device *dev, u32 pasid, int mode)
+{
+ struct intel_iommu *iommu = device_to_iommu(dev, NULL, NULL);
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct device_domain_info *info;
+ unsigned long flags;
+ int ret = 0;
+
+ info = get_domain_info(dev);
+ if (!info)
+ return -ENODEV;
+
+ if (!dev_is_pci(dev) || !sm_supported(info->iommu))
+ return -EINVAL;
+
+ if (intel_iommu_enable_pasid(info->iommu, dev))
+ return -ENODEV;
+
+ spin_lock_irqsave(&iommu->lock, flags);
+ switch (mode) {
+ case IOMMU_DMA_PASID_BYPASS:
+ dev_dbg(dev, "%s PT mode", __func__);
+ /* As a precaution, translation request should be responded with
+ * physical address.
+ */
+ if (!hw_pass_through) {
+ ret = -ENODEV;
+ goto exit_unlock;
+ }
+ /* HW may use large page for ATS */
+ pci_disable_ats(pdev);
+ ret = intel_pasid_setup_pass_through(info->iommu, info->domain,
+ dev, pasid);
+ if (ret)
+ dev_err(dev, "Failed SPASID %d BYPASS", pasid);
+ break;
+ case IOMMU_DMA_PASID_IOVA:
+ dev_dbg(dev, "%s IOVA mode", __func__);
+ /*
+ * We could use SL but FL is preferred for consistency with VM
+ * where vIOMMU exposes FL only cap
+ */
+ if (!domain_use_first_level(info->domain))
+ return -EINVAL;
+ /* To be used for IOTLB flush at PASID granularity */
+ info->domain->s_pasid = pasid;
+ ret = domain_setup_first_level(info->iommu, info->domain, dev,
+ pasid);
+ break;
+ default:
+ dev_err(dev, "Invalid PASID DMA mode %d", mode);
+ ret = -EINVAL;
+ goto exit_unlock;
+ }
+ info->pasid_mode = mode;
+exit_unlock:
+ spin_unlock_irqrestore(&iommu->lock, flags);
+
+ return ret;
+}
+
+static int intel_disable_pasid_dma(struct device *dev)
+{
+ struct device_domain_info *info;
+ int ret = 0;
+
+ info = get_domain_info(dev);
+ if (!info)
+ return -ENODEV;
+
+ if (!dev_is_pci(dev) || !sm_supported(info->iommu))
+ return -EINVAL;
+
+ if (intel_iommu_enable_pasid(info->iommu, dev))
+ return -ENODEV;
+
+ if (!dev->iommu) {
+ dev_err(dev, "No IOMMU params");
+ return -ENODEV;
+ }
+ dev_info(dev, "Tearing down DMA PASID %d", info->domain->s_pasid);
+ intel_pasid_tear_down_entry(info->iommu, info->dev, info->domain->s_pasid, false);
+
+ info->domain->s_pasid = 0;
+ return ret;
+}
+
const struct iommu_ops intel_iommu_ops = {
.capable = intel_iommu_capable,
.domain_alloc = intel_iommu_domain_alloc,
@@ -5573,6 +5664,8 @@ const struct iommu_ops intel_iommu_ops = {
.sva_get_pasid = intel_svm_get_pasid,
.page_response = intel_svm_page_response,
#endif
+ .enable_pasid_dma = intel_enable_pasid_dma,
+ .disable_pasid_dma = intel_disable_pasid_dma,
};
static void quirk_iommu_igfx(struct pci_dev *dev)
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index 03faf20a6817..8940759f759e 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -21,6 +21,7 @@
#include <linux/dmar.h>
#include <linux/ioasid.h>
#include <linux/bitfield.h>
+#include <linux/dma-iommu.h>
#include <asm/cacheflush.h>
#include <asm/iommu.h>
@@ -571,7 +572,10 @@ struct dmar_domain {
* The default pasid used for non-SVM
* traffic on mediated devices.
*/
-
+ u32 s_pasid; /*
+ * Supervisor PASID used for in-kernel
+ * DMA request with PASID.
+ */
struct iommu_domain domain; /* generic domain data structure for
iommu core */
};
@@ -652,6 +656,7 @@ struct device_domain_info {
struct intel_iommu *iommu; /* IOMMU used by this device */
struct dmar_domain *domain; /* pointer to domain */
struct pasid_table *pasid_table; /* pasid table */
+ enum iommu_dma_pasid_mode pasid_mode; /* DMA PASID address mode */
};
static inline void __iommu_flush_cache(
--
2.25.1
next prev parent reply other threads:[~2021-09-22 5:13 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-21 20:29 [RFC 0/7] Support in-kernel DMA with PASID and SVA Jacob Pan
2021-09-21 20:29 ` [RFC 1/7] ioasid: reserve special PASID for in-kernel DMA Jacob Pan
2021-09-21 20:29 ` [RFC 2/7] dma-iommu: Add API for DMA request with PASID Jacob Pan
2021-09-21 20:29 ` Jacob Pan [this message]
2021-09-21 20:29 ` [RFC 4/7] dma-iommu: Add support for DMA w/ PASID in KVA Jacob Pan
2021-09-21 20:29 ` [RFC 5/7] iommu/vt-d: Add support for KVA PASID mode Jacob Pan
2021-09-21 20:29 ` [RFC 6/7] iommu: Add KVA map API Jacob Pan
2021-09-21 20:29 ` [RFC 7/7] dma/idxd: Use dma-iommu PASID API instead of SVA lib Jacob Pan
2021-09-22 17:04 ` [RFC 0/7] Support in-kernel DMA with PASID and SVA Jason Gunthorpe
2021-09-29 19:37 ` Jacob Pan
2021-09-29 19:39 ` Jason Gunthorpe
2021-09-29 22:57 ` Jacob Pan
2021-09-29 23:43 ` Jason Gunthorpe
2021-09-30 14:22 ` Campin, Mike
2021-09-30 15:21 ` Jacob Pan
2021-10-01 12:24 ` Barry Song
2021-10-01 12:36 ` Jason Gunthorpe
2021-10-01 12:45 ` Barry Song
2021-10-04 16:40 ` Jacob Pan
2021-10-04 18:21 ` Jason Gunthorpe
2021-10-07 5:43 ` Barry Song
2021-10-07 11:32 ` Jason Gunthorpe
2021-10-07 11:54 ` Barry Song
2021-10-07 11:59 ` Jason Gunthorpe
2021-10-07 17:50 ` Jacob Pan
2021-10-07 17:48 ` Jason Gunthorpe
2021-10-07 18:08 ` Jacob Pan
2021-10-07 19:11 ` Jacob Pan
2021-10-07 19:10 ` Jason Gunthorpe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1632256181-36071-4-git-send-email-jacob.jun.pan@linux.intel.com \
--to=jacob.jun.pan@linux.intel.com \
--cc=ashok.raj@intel.com \
--cc=baolu.lu@linux.intel.com \
--cc=dave.jiang@intel.com \
--cc=hch@infradead.org \
--cc=iommu@lists.linux-foundation.org \
--cc=jgg@nvidia.com \
--cc=joro@8bytes.org \
--cc=kevin.tian@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mike.campin@intel.com \
--cc=sanjay.k.kumar@intel.com \
--cc=tony.luck@intel.com \
--cc=yi.l.liu@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox