From: Jacob Pan <jacob.jun.pan@linux.intel.com>
To: LKML <linux-kernel@vger.kernel.org>,
iommu@lists.linux.dev, "Robin Murphy" <robin.murphy@arm.com>,
Jason Gunthorpe <jgg@nvidia.com>,
"Lu Baolu" <baolu.lu@linux.intel.com>,
Joerg Roedel <joro@8bytes.org>,
dmaengine@vger.kernel.org, vkoul@kernel.org
Cc: "Will Deacon" <will@kernel.org>,
David Woodhouse <dwmw2@infradead.org>,
Raj Ashok <ashok.raj@intel.com>,
"Tian, Kevin" <kevin.tian@intel.com>, Yi Liu <yi.l.liu@intel.com>,
"Yu, Fenghua" <fenghua.yu@intel.com>,
Dave Jiang <dave.jiang@intel.com>,
Tony Luck <tony.luck@intel.com>,
"Zanussi, Tom" <tom.zanussi@intel.com>,
narayan.ranganathan@intel.com,
Jacob Pan <jacob.jun.pan@linux.intel.com>
Subject: [PATCH v5 6/7] iommu/vt-d: Implement set_dev_pasid domain op
Date: Thu, 27 Apr 2023 10:49:36 -0700 [thread overview]
Message-ID: <20230427174937.471668-7-jacob.jun.pan@linux.intel.com> (raw)
In-Reply-To: <20230427174937.471668-1-jacob.jun.pan@linux.intel.com>
Devices that use ENQCMDS to submit work on buffers mapped by DMA API
must attach a PASID to the default domain of the device. In preparation
for this use case, this patch implements set_dev_pasid() for the
default_domain_ops.
If the device context has not been set up prior to this call, this will
set up the device context in addition to PASID attachment.
Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com>
---
drivers/iommu/intel/iommu.c | 92 ++++++++++++++++++++++++++++++-------
1 file changed, 76 insertions(+), 16 deletions(-)
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 388453a7415e..f9d6c31cdc8e 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -278,6 +278,8 @@ static LIST_HEAD(dmar_satc_units);
list_for_each_entry(rmrr, &dmar_rmrr_units, list)
static void device_block_translation(struct device *dev);
+static void intel_iommu_detach_device_pasid(struct iommu_domain *domain,
+ struct device *dev, ioasid_t pasid);
static void intel_iommu_domain_free(struct iommu_domain *domain);
int dmar_disabled = !IS_ENABLED(CONFIG_INTEL_IOMMU_DEFAULT_ON);
@@ -4091,8 +4093,7 @@ static void device_block_translation(struct device *dev)
iommu_disable_pci_caps(info);
if (!dev_is_real_dma_subdevice(dev)) {
if (sm_supported(iommu))
- intel_pasid_tear_down_entry(iommu, dev,
- IOMMU_DEF_RID_PASID, false);
+ intel_iommu_detach_device_pasid(&info->domain->domain, dev, IOMMU_DEF_RID_PASID);
else
domain_context_clear(info);
}
@@ -4761,28 +4762,86 @@ static void intel_iommu_iotlb_sync_map(struct iommu_domain *domain,
__mapping_notify_one(info->iommu, dmar_domain, pfn, pages);
}
-static void intel_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid)
+static void intel_iommu_detach_device_pasid(struct iommu_domain *domain,
+ struct device *dev, ioasid_t pasid)
{
- struct intel_iommu *iommu = device_to_iommu(dev, NULL, NULL);
- struct iommu_domain *domain;
+ struct device_domain_info *info = dev_iommu_priv_get(dev);
+ struct dmar_domain *dmar_domain = to_dmar_domain(domain);
+ struct device_pasid_info *i, *dev_pasid = NULL;
+ struct intel_iommu *iommu = info->iommu;
+ unsigned long flags;
- /* Domain type specific cleanup: */
- domain = iommu_get_domain_for_dev_pasid(dev, pasid, 0);
- if (domain) {
- switch (domain->type) {
- case IOMMU_DOMAIN_SVA:
- intel_svm_remove_dev_pasid(dev, pasid);
- break;
- default:
- /* should never reach here */
- WARN_ON(1);
+ spin_lock_irqsave(&dmar_domain->lock, flags);
+ list_for_each_entry(i, &dmar_domain->dev_pasids, link_domain) {
+ if (i->dev == dev && i->pasid == pasid) {
+ list_del(&i->link_domain);
+ dev_pasid = i;
break;
}
}
+ spin_unlock_irqrestore(&dmar_domain->lock, flags);
+ if (WARN_ON(!dev_pasid))
+ return;
+
+ /* PASID entry already cleared during SVA unbind */
+ if (domain->type != IOMMU_DOMAIN_SVA)
+ intel_pasid_tear_down_entry(iommu, dev, pasid, false);
+
+ kfree(dev_pasid);
+}
+
+static void intel_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid)
+{
+ struct device_domain_info *info = dev_iommu_priv_get(dev);
+ struct dmar_domain *dmar_domain;
+ struct iommu_domain *domain;
+
+ domain = iommu_get_domain_for_dev_pasid(dev, pasid, 0);
+ dmar_domain = to_dmar_domain(domain);
+
+ /*
+ * SVA Domain type specific cleanup: Not ideal but not until we have
+ * IOPF capable domain specific ops, we need this special case.
+ */
+ if (domain->type == IOMMU_DOMAIN_SVA)
+ return intel_svm_remove_dev_pasid(dev, pasid);
- intel_pasid_tear_down_entry(iommu, dev, pasid, false);
+ intel_iommu_detach_device_pasid(domain, dev, pasid);
+ domain_detach_iommu(dmar_domain, info->iommu);
}
+static int intel_iommu_attach_device_pasid(struct iommu_domain *domain,
+ struct device *dev, ioasid_t pasid)
+{
+ struct device_domain_info *info = dev_iommu_priv_get(dev);
+ struct dmar_domain *dmar_domain = to_dmar_domain(domain);
+ struct intel_iommu *iommu = info->iommu;
+ int ret;
+
+ if (!pasid_supported(iommu))
+ return -ENODEV;
+
+ ret = prepare_domain_attach_device(domain, dev);
+ if (ret)
+ return ret;
+
+ /*
+ * Most likely the device context has already been set up, will only
+ * take a domain ID reference. Otherwise, device context will be set
+ * up here.
+ * The upper layer APIs make no assumption about the ordering between
+ * device attachment and the PASID attachment.
+ */
+ ret = dmar_domain_attach_device(to_dmar_domain(domain), dev);
+ if (ret) {
+ dev_err(dev, "Attach device failed\n");
+ return ret;
+ }
+ return dmar_domain_attach_device_pasid(dmar_domain, iommu, dev, pasid);
+}
+
+
+
const struct iommu_ops intel_iommu_ops = {
.capable = intel_iommu_capable,
.domain_alloc = intel_iommu_domain_alloc,
@@ -4802,6 +4861,7 @@ const struct iommu_ops intel_iommu_ops = {
#endif
.default_domain_ops = &(const struct iommu_domain_ops) {
.attach_dev = intel_iommu_attach_device,
+ .set_dev_pasid = intel_iommu_attach_device_pasid,
.map_pages = intel_iommu_map_pages,
.unmap_pages = intel_iommu_unmap_pages,
.iotlb_sync_map = intel_iommu_iotlb_sync_map,
--
2.25.1
next prev parent reply other threads:[~2023-04-27 17:46 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-27 17:49 [PATCH v5 0/7] Re-enable IDXD kernel workqueue under DMA API Jacob Pan
2023-04-27 17:49 ` [PATCH v5 1/7] iommu: Generalize default PCIe requester ID PASID Jacob Pan
2023-04-28 9:38 ` Tian, Kevin
2023-04-28 15:56 ` Jacob Pan
2023-05-05 8:28 ` Tian, Kevin
2023-05-09 20:39 ` Jacob Pan
2023-04-27 17:49 ` [PATCH v5 2/7] iommu/sva: Explicitly exclude RID_PASID from SVA Jacob Pan
2023-04-28 9:40 ` Tian, Kevin
2023-04-28 15:56 ` Jacob Pan
2023-04-27 17:49 ` [PATCH v5 3/7] iommu: Move global PASID allocation from SVA to core Jacob Pan
2023-04-28 9:46 ` Tian, Kevin
2023-04-28 16:40 ` Jacob Pan
2023-05-03 6:32 ` Baolu Lu
2023-05-04 21:26 ` Jacob Pan
2023-04-27 17:49 ` [PATCH v5 4/7] iommu/vt-d: Factoring out PASID set up helper function Jacob Pan
2023-04-28 9:47 ` Tian, Kevin
2023-05-03 6:37 ` Baolu Lu
2023-05-04 21:39 ` Jacob Pan
2023-05-04 21:27 ` Jacob Pan
2023-04-27 17:49 ` [PATCH v5 5/7] iommu/vt-d: Prepare PASID attachment beyond RID_PASID Jacob Pan
2023-05-03 6:49 ` Baolu Lu
2023-05-04 21:53 ` Jacob Pan
2023-04-27 17:49 ` Jacob Pan [this message]
2023-05-03 7:26 ` [PATCH v5 6/7] iommu/vt-d: Implement set_dev_pasid domain op Baolu Lu
2023-05-04 23:03 ` Jacob Pan
2023-05-05 2:58 ` Baolu Lu
2023-05-05 20:32 ` Jacob Pan
2023-04-27 17:49 ` [PATCH v5 7/7] dmaengine/idxd: Re-enable kernel workqueue under DMA API Jacob Pan
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=20230427174937.471668-7-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=dmaengine@vger.kernel.org \
--cc=dwmw2@infradead.org \
--cc=fenghua.yu@intel.com \
--cc=iommu@lists.linux.dev \
--cc=jgg@nvidia.com \
--cc=joro@8bytes.org \
--cc=kevin.tian@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=narayan.ranganathan@intel.com \
--cc=robin.murphy@arm.com \
--cc=tom.zanussi@intel.com \
--cc=tony.luck@intel.com \
--cc=vkoul@kernel.org \
--cc=will@kernel.org \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.