public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
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 2/7] dma-iommu: Add API for DMA request with PASID
Date: Tue, 21 Sep 2021 13:29:36 -0700	[thread overview]
Message-ID: <1632256181-36071-3-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>

DMA-API is the standard way for device drivers to perform in-kernel
DMA requests. If security is on, isolation is enforced by the IOMMU at
requester ID (RID) granularity. With the introduction of process address
space ID (PASID), DMA security is enforced per RID+PASID
granularity. On some modern platforms, DMA request with PASID is the
only option available. e.g. The shared work queues in Intel Data
Streaming Accelerators (DSA).
To support DMA with PASID while maintaining the ubiquitous usage of DMA
API, this patch introduces a new IOMMU DMA API that supports two
addressing modes:
1. Physical address or bypass mode. This is similar to DMA direct mode,
where trusted devices can DMA passthrough IOMMU.
2. IOVA mode that abides DMA APIs. Once set up, callers can use DMA API
as-is. DMA requests w/ and w/o PASID will be mapped by the same page
tables.  i.e. the default DMA domain will be used by both RID and
RID+PASID.

Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com>
---
 drivers/iommu/dma-iommu.c | 54 +++++++++++++++++++++++++++++++++++++++
 include/linux/dma-iommu.h | 12 +++++++++
 include/linux/iommu.h     |  2 ++
 3 files changed, 68 insertions(+)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 7bcdd1205535..490731659def 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -174,6 +174,60 @@ void iommu_put_dma_cookie(struct iommu_domain *domain)
 }
 EXPORT_SYMBOL(iommu_put_dma_cookie);
 
+/**
+ * iommu_dma_pasid_enable --Enable device DMA request with PASID
+ * @dev:	Device to be enabled
+ * @mode:	DMA addressing mode
+ *
+ * The following mutually exclusive DMA addressing modes are supported:
+ *
+ *  1. Physical address or bypass mode. This is similar to DMA direct where
+ *     trusted devices can DMA pass-through IOMMU.
+ *
+ *  2. IOVA mode. This abides DMA APIs. Once set up, callers can use DMA API
+ *     as-is. DMA request w/ and w/o PASID will be mapped by the same page
+ *     tables. PCI requester ID (RID) and RID+PASID will be pointed to the same
+ *     PGD. i.e. the default DMA domain will be used by both RID and RID+PASID.
+ *
+ * @return the supervisor PASID to be used for DMA. Or INVALID_IOASID upon
+ *     failure.
+ */
+int iommu_dma_pasid_enable(struct device *dev,
+			   enum iommu_dma_pasid_mode mode)
+{
+	int pasid = INVALID_IOASID;
+	struct iommu_domain *dom = NULL;
+
+	/* TODO: only allow a single mode each time, track PASID DMA enabling
+	 * status per device. Perhaps add a flag in struct device.dev_iommu.
+	 */
+
+	/* Call vendor drivers to handle IOVA, bypass mode */
+	dom = iommu_get_domain_for_dev(dev);
+	if (dom->ops->enable_pasid_dma(dev, IOASID_DMA_PASID, mode)) {
+		dev_dbg(dev, "Failed to enable DMA pasid in mode %d", mode);
+		goto exit;
+	}
+	pasid = IOASID_DMA_PASID;
+
+	dev_dbg(dev, "Enable DMA pasid %d in mode %d", pasid, mode);
+	goto exit;
+exit:
+	return pasid;
+}
+EXPORT_SYMBOL(iommu_dma_pasid_enable);
+
+int iommu_dma_pasid_disable(struct device *dev)
+{
+	struct iommu_domain *dom;
+
+	/* Call vendor iommu ops to clean up supervisor PASID context */
+	dom = iommu_get_domain_for_dev(dev);
+
+	return dom->ops->disable_pasid_dma(dev);
+}
+EXPORT_SYMBOL(iommu_dma_pasid_disable);
+
 /**
  * iommu_dma_get_resv_regions - Reserved region driver helper
  * @dev: Device from iommu_get_resv_regions()
diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
index 6e75a2d689b4..3c1555e0fd51 100644
--- a/include/linux/dma-iommu.h
+++ b/include/linux/dma-iommu.h
@@ -17,6 +17,18 @@
 int iommu_get_dma_cookie(struct iommu_domain *domain);
 int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base);
 void iommu_put_dma_cookie(struct iommu_domain *domain);
+enum iommu_dma_pasid_mode {
+	/* Pass-through mode, use physical address */
+	IOMMU_DMA_PASID_BYPASS = 1,
+	/* Compatible with DMA APIs, same mapping as DMA w/o PASID */
+	IOMMU_DMA_PASID_IOVA,
+};
+/* For devices that can do DMA request with PASID, setup the system
+ * based on the address mode selected.
+ */
+int iommu_dma_pasid_enable(struct device *dev,
+			   enum iommu_dma_pasid_mode mode);
+int iommu_dma_pasid_disable(struct device *dev);
 
 /* Setup call for arch DMA mapping code */
 void iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 32d448050bf7..610cbfd03e6b 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -283,6 +283,8 @@ struct iommu_ops {
 
 	int (*def_domain_type)(struct device *dev);
 
+	int (*enable_pasid_dma)(struct device *dev, u32 pasid, int mode);
+	int (*disable_pasid_dma)(struct device *dev);
 	unsigned long pgsize_bitmap;
 	struct module *owner;
 };
-- 
2.25.1


  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 ` Jacob Pan [this message]
2021-09-21 20:29 ` [RFC 3/7] iommu/vt-d: Add DMA w/ PASID support for PA and IOVA Jacob Pan
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-3-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