All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jacob Pan <jacob.jun.pan@linux.intel.com>
To: "Tian, Kevin" <kevin.tian@intel.com>
Cc: "iommu@lists.linux-foundation.org"
	<iommu@lists.linux-foundation.org>,
	LKML <linux-kernel@vger.kernel.org>,
	"dmaengine@vger.kernel.org" <dmaengine@vger.kernel.org>,
	Joerg Roedel <joro@8bytes.org>,
	David Woodhouse <dwmw2@infradead.org>,
	Jean-Philippe Brucker <jean-philippe@linaro.com>,
	"Lu Baolu" <baolu.lu@linux.intel.com>,
	Jason Gunthorpe <jgg@nvidia.com>,
	Christoph Hellwig <hch@infradead.org>,
	"vkoul@kernel.org" <vkoul@kernel.org>,
	"robin.murphy@arm.com" <robin.murphy@arm.com>,
	"will@kernel.org" <will@kernel.org>,
	"Liu, Yi L" <yi.l.liu@intel.com>,
	"Jiang, Dave" <dave.jiang@intel.com>,
	"Raj, Ashok" <ashok.raj@intel.com>,
	Eric Auger <eric.auger@redhat.com>,
	jacob.jun.pan@linux.intel.com
Subject: Re: [PATCH v4 4/6] iommu: Add PASID support for DMA mapping API users
Date: Mon, 23 May 2022 08:23:59 -0700	[thread overview]
Message-ID: <20220523082359.74fb435b@jacob-builder> (raw)
In-Reply-To: <BL1PR11MB5271E995E160E0C6A6C0C89A8CD49@BL1PR11MB5271.namprd11.prod.outlook.com>

Hi Kevin,

On Mon, 23 May 2022 08:25:33 +0000, "Tian, Kevin" <kevin.tian@intel.com>
wrote:

> > From: Jacob Pan <jacob.jun.pan@linux.intel.com>
> > Sent: Thursday, May 19, 2022 2:21 AM
> > 
> > DMA mapping API is the de facto standard for in-kernel DMA. It operates
> > on a per device/RID basis which is not PASID-aware.
> > 
> > Some modern devices such as Intel Data Streaming Accelerator, PASID is
> > required for certain work submissions. To allow such devices use DMA
> > mapping API, we need the following functionalities:
> > 1. Provide device a way to retrieve a PASID for work submission within
> > the kernel
> > 2. Enable the kernel PASID on the IOMMU for the device
> > 3. Attach the kernel PASID to the device's default DMA domain, let it
> > be IOVA or physical address in case of pass-through.
> > 
> > This patch introduces a driver facing API that enables DMA API
> > PASID usage. Once enabled, device drivers can continue to use DMA APIs
> > as is. There is no difference in dma_handle between without PASID and
> > with PASID.
> > 
> > Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com>
> > ---
> >  drivers/iommu/dma-iommu.c | 114
> > ++++++++++++++++++++++++++++++++++++++
> >  include/linux/dma-iommu.h |   3 +
> >  2 files changed, 117 insertions(+)
> > 
> > diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
> > index 1ca85d37eeab..6ad7ba619ef0 100644
> > --- a/drivers/iommu/dma-iommu.c
> > +++ b/drivers/iommu/dma-iommu.c
> > @@ -34,6 +34,8 @@ struct iommu_dma_msi_page {
> >  	phys_addr_t		phys;
> >  };
> > 
> > +static DECLARE_IOASID_SET(iommu_dma_pasid);
> > +
> >  enum iommu_dma_cookie_type {
> >  	IOMMU_DMA_IOVA_COOKIE,
> >  	IOMMU_DMA_MSI_COOKIE,
> > @@ -370,6 +372,118 @@ void iommu_put_dma_cookie(struct
> > iommu_domain *domain)
> >  	domain->iova_cookie = NULL;
> >  }
> > 
> > +/* Protect iommu_domain DMA PASID data */
> > +static DEFINE_MUTEX(dma_pasid_lock);
> > +/**
> > + * iommu_attach_dma_pasid --Attach a PASID for in-kernel DMA. Use the
> > device's
> > + * DMA domain.
> > + * @dev: Device to be enabled
> > + * @pasid: The returned kernel PASID to be used for DMA
> > + *
> > + * DMA request with PASID will be mapped the same way as the legacy
> > DMA.
> > + * If the device is in pass-through, PASID will also pass-through. If
> > the
> > + * device is in IOVA, the PASID will point to the same IOVA page table.
> > + *
> > + * @return err code or 0 on success
> > + */
> > +int iommu_attach_dma_pasid(struct device *dev, ioasid_t *pasid)  
> 
> iommu_attach_dma_domain_pasid? 'dma_pasid' is too broad from
> a API p.o.v.
> 
I agree dma_pasid is too broad, technically it is dma_api_pasid but seems
too long.
My concern with dma_domain_pasid is that the pasid can also be used for
identity domain.

> > +{
> > +	struct iommu_domain *dom;
> > +	ioasid_t id, max;
> > +	int ret = 0;
> > +
> > +	dom = iommu_get_domain_for_dev(dev);
> > +	if (!dom || !dom->ops || !dom->ops->attach_dev_pasid)
> > +		return -ENODEV;
> > +
> > +	/* Only support domain types that DMA API can be used */
> > +	if (dom->type == IOMMU_DOMAIN_UNMANAGED ||
> > +	    dom->type == IOMMU_DOMAIN_BLOCKED) {
> > +		dev_warn(dev, "Invalid domain type %d", dom->type);
> > +		return -EPERM;
> > +	}  
> 
> WARN_ON.
> 
> and probably we can just check whether domain is default domain here.
> 
good point, I will just use
struct iommu_domain *def_domain = iommu_get_dma_domain(dev);

> > +
> > +	mutex_lock(&dma_pasid_lock);
> > +	id = dom->dma_pasid;
> > +	if (!id) {
> > +		/*
> > +		 * First device to use PASID in its DMA domain,
> > allocate
> > +		 * a single PASID per DMA domain is all we need, it is
> > also
> > +		 * good for performance when it comes down to IOTLB
> > flush.
> > +		 */
> > +		max = 1U << dev->iommu->pasid_bits;
> > +		if (!max) {
> > +			ret = -EINVAL;
> > +			goto done_unlock;
> > +		}
> > +
> > +		id = ioasid_alloc(&iommu_dma_pasid, 1, max, dev);
> > +		if (id == INVALID_IOASID) {
> > +			ret = -ENOMEM;
> > +			goto done_unlock;
> > +		}
> > +
> > +		dom->dma_pasid = id;
> > +		atomic_set(&dom->dma_pasid_users, 1);  
> 
> this is always accessed with lock held hence no need to be atomic.
> 
good catch, will fix

> > +	}
> > +
> > +	ret = iommu_attach_device_pasid(dom, dev, id);
> > +	if (!ret) {
> > +		*pasid = id;
> > +		atomic_inc(&dom->dma_pasid_users);
> > +		goto done_unlock;
> > +	}
> > +
> > +	if (atomic_dec_and_test(&dom->dma_pasid_users)) {
> > +		ioasid_free(id);
> > +		dom->dma_pasid = 0;
> > +	}
> > +done_unlock:
> > +	mutex_unlock(&dma_pasid_lock);
> > +	return ret;
> > +}
> > +EXPORT_SYMBOL(iommu_attach_dma_pasid);
> > +
> > +/**
> > + * iommu_detach_dma_pasid --Disable in-kernel DMA request with PASID
> > + * @dev:	Device's PASID DMA to be disabled
> > + *
> > + * It is the device driver's responsibility to ensure no more incoming
> > DMA
> > + * requests with the kernel PASID before calling this function. IOMMU
> > driver
> > + * ensures PASID cache, IOTLBs related to the kernel PASID are cleared
> > and
> > + * drained.
> > + *
> > + */
> > +void iommu_detach_dma_pasid(struct device *dev)
> > +{
> > +	struct iommu_domain *dom;
> > +	ioasid_t pasid;
> > +
> > +	dom = iommu_get_domain_for_dev(dev);
> > +	if (WARN_ON(!dom || !dom->ops || !dom->ops->detach_dev_pasid))
> > +		return;
> > +
> > +	/* Only support DMA API managed domain type */
> > +	if (WARN_ON(dom->type == IOMMU_DOMAIN_UNMANAGED ||
> > +		    dom->type == IOMMU_DOMAIN_BLOCKED))
> > +		return;
> > +
> > +	mutex_lock(&dma_pasid_lock);
> > +	pasid = iommu_get_pasid_from_domain(dev, dom);
> > +	if (!pasid || pasid == INVALID_IOASID) {
> > +		dev_err(dev, "No valid DMA PASID attached\n");
> > +		mutex_unlock(&dma_pasid_lock);
> > +		return;
> > +	}  
> 
> here just use dom->dma_pasid and let iommu driver to figure out
> underlying whether this device has been attached to the domain
> with the said pasid.
> 
Yeah, I am checking the pasid matching in the iommu driver. My thinking is
that here is a quick sanity check in the common code to rule out invalid value.


Thanks a lot!


Jacob

WARNING: multiple messages have this Message-ID (diff)
From: Jacob Pan <jacob.jun.pan@linux.intel.com>
To: "Tian, Kevin" <kevin.tian@intel.com>
Cc: "vkoul@kernel.org" <vkoul@kernel.org>,
	"Jiang, Dave" <dave.jiang@intel.com>,
	"Raj, Ashok" <ashok.raj@intel.com>,
	"will@kernel.org" <will@kernel.org>,
	David Woodhouse <dwmw2@infradead.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Christoph Hellwig <hch@infradead.org>,
	"iommu@lists.linux-foundation.org"
	<iommu@lists.linux-foundation.org>,
	Jason Gunthorpe <jgg@nvidia.com>,
	"dmaengine@vger.kernel.org" <dmaengine@vger.kernel.org>,
	"robin.murphy@arm.com" <robin.murphy@arm.com>,
	Jean-Philippe Brucker <jean-philippe@linaro.com>
Subject: Re: [PATCH v4 4/6] iommu: Add PASID support for DMA mapping API users
Date: Mon, 23 May 2022 08:23:59 -0700	[thread overview]
Message-ID: <20220523082359.74fb435b@jacob-builder> (raw)
In-Reply-To: <BL1PR11MB5271E995E160E0C6A6C0C89A8CD49@BL1PR11MB5271.namprd11.prod.outlook.com>

Hi Kevin,

On Mon, 23 May 2022 08:25:33 +0000, "Tian, Kevin" <kevin.tian@intel.com>
wrote:

> > From: Jacob Pan <jacob.jun.pan@linux.intel.com>
> > Sent: Thursday, May 19, 2022 2:21 AM
> > 
> > DMA mapping API is the de facto standard for in-kernel DMA. It operates
> > on a per device/RID basis which is not PASID-aware.
> > 
> > Some modern devices such as Intel Data Streaming Accelerator, PASID is
> > required for certain work submissions. To allow such devices use DMA
> > mapping API, we need the following functionalities:
> > 1. Provide device a way to retrieve a PASID for work submission within
> > the kernel
> > 2. Enable the kernel PASID on the IOMMU for the device
> > 3. Attach the kernel PASID to the device's default DMA domain, let it
> > be IOVA or physical address in case of pass-through.
> > 
> > This patch introduces a driver facing API that enables DMA API
> > PASID usage. Once enabled, device drivers can continue to use DMA APIs
> > as is. There is no difference in dma_handle between without PASID and
> > with PASID.
> > 
> > Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com>
> > ---
> >  drivers/iommu/dma-iommu.c | 114
> > ++++++++++++++++++++++++++++++++++++++
> >  include/linux/dma-iommu.h |   3 +
> >  2 files changed, 117 insertions(+)
> > 
> > diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
> > index 1ca85d37eeab..6ad7ba619ef0 100644
> > --- a/drivers/iommu/dma-iommu.c
> > +++ b/drivers/iommu/dma-iommu.c
> > @@ -34,6 +34,8 @@ struct iommu_dma_msi_page {
> >  	phys_addr_t		phys;
> >  };
> > 
> > +static DECLARE_IOASID_SET(iommu_dma_pasid);
> > +
> >  enum iommu_dma_cookie_type {
> >  	IOMMU_DMA_IOVA_COOKIE,
> >  	IOMMU_DMA_MSI_COOKIE,
> > @@ -370,6 +372,118 @@ void iommu_put_dma_cookie(struct
> > iommu_domain *domain)
> >  	domain->iova_cookie = NULL;
> >  }
> > 
> > +/* Protect iommu_domain DMA PASID data */
> > +static DEFINE_MUTEX(dma_pasid_lock);
> > +/**
> > + * iommu_attach_dma_pasid --Attach a PASID for in-kernel DMA. Use the
> > device's
> > + * DMA domain.
> > + * @dev: Device to be enabled
> > + * @pasid: The returned kernel PASID to be used for DMA
> > + *
> > + * DMA request with PASID will be mapped the same way as the legacy
> > DMA.
> > + * If the device is in pass-through, PASID will also pass-through. If
> > the
> > + * device is in IOVA, the PASID will point to the same IOVA page table.
> > + *
> > + * @return err code or 0 on success
> > + */
> > +int iommu_attach_dma_pasid(struct device *dev, ioasid_t *pasid)  
> 
> iommu_attach_dma_domain_pasid? 'dma_pasid' is too broad from
> a API p.o.v.
> 
I agree dma_pasid is too broad, technically it is dma_api_pasid but seems
too long.
My concern with dma_domain_pasid is that the pasid can also be used for
identity domain.

> > +{
> > +	struct iommu_domain *dom;
> > +	ioasid_t id, max;
> > +	int ret = 0;
> > +
> > +	dom = iommu_get_domain_for_dev(dev);
> > +	if (!dom || !dom->ops || !dom->ops->attach_dev_pasid)
> > +		return -ENODEV;
> > +
> > +	/* Only support domain types that DMA API can be used */
> > +	if (dom->type == IOMMU_DOMAIN_UNMANAGED ||
> > +	    dom->type == IOMMU_DOMAIN_BLOCKED) {
> > +		dev_warn(dev, "Invalid domain type %d", dom->type);
> > +		return -EPERM;
> > +	}  
> 
> WARN_ON.
> 
> and probably we can just check whether domain is default domain here.
> 
good point, I will just use
struct iommu_domain *def_domain = iommu_get_dma_domain(dev);

> > +
> > +	mutex_lock(&dma_pasid_lock);
> > +	id = dom->dma_pasid;
> > +	if (!id) {
> > +		/*
> > +		 * First device to use PASID in its DMA domain,
> > allocate
> > +		 * a single PASID per DMA domain is all we need, it is
> > also
> > +		 * good for performance when it comes down to IOTLB
> > flush.
> > +		 */
> > +		max = 1U << dev->iommu->pasid_bits;
> > +		if (!max) {
> > +			ret = -EINVAL;
> > +			goto done_unlock;
> > +		}
> > +
> > +		id = ioasid_alloc(&iommu_dma_pasid, 1, max, dev);
> > +		if (id == INVALID_IOASID) {
> > +			ret = -ENOMEM;
> > +			goto done_unlock;
> > +		}
> > +
> > +		dom->dma_pasid = id;
> > +		atomic_set(&dom->dma_pasid_users, 1);  
> 
> this is always accessed with lock held hence no need to be atomic.
> 
good catch, will fix

> > +	}
> > +
> > +	ret = iommu_attach_device_pasid(dom, dev, id);
> > +	if (!ret) {
> > +		*pasid = id;
> > +		atomic_inc(&dom->dma_pasid_users);
> > +		goto done_unlock;
> > +	}
> > +
> > +	if (atomic_dec_and_test(&dom->dma_pasid_users)) {
> > +		ioasid_free(id);
> > +		dom->dma_pasid = 0;
> > +	}
> > +done_unlock:
> > +	mutex_unlock(&dma_pasid_lock);
> > +	return ret;
> > +}
> > +EXPORT_SYMBOL(iommu_attach_dma_pasid);
> > +
> > +/**
> > + * iommu_detach_dma_pasid --Disable in-kernel DMA request with PASID
> > + * @dev:	Device's PASID DMA to be disabled
> > + *
> > + * It is the device driver's responsibility to ensure no more incoming
> > DMA
> > + * requests with the kernel PASID before calling this function. IOMMU
> > driver
> > + * ensures PASID cache, IOTLBs related to the kernel PASID are cleared
> > and
> > + * drained.
> > + *
> > + */
> > +void iommu_detach_dma_pasid(struct device *dev)
> > +{
> > +	struct iommu_domain *dom;
> > +	ioasid_t pasid;
> > +
> > +	dom = iommu_get_domain_for_dev(dev);
> > +	if (WARN_ON(!dom || !dom->ops || !dom->ops->detach_dev_pasid))
> > +		return;
> > +
> > +	/* Only support DMA API managed domain type */
> > +	if (WARN_ON(dom->type == IOMMU_DOMAIN_UNMANAGED ||
> > +		    dom->type == IOMMU_DOMAIN_BLOCKED))
> > +		return;
> > +
> > +	mutex_lock(&dma_pasid_lock);
> > +	pasid = iommu_get_pasid_from_domain(dev, dom);
> > +	if (!pasid || pasid == INVALID_IOASID) {
> > +		dev_err(dev, "No valid DMA PASID attached\n");
> > +		mutex_unlock(&dma_pasid_lock);
> > +		return;
> > +	}  
> 
> here just use dom->dma_pasid and let iommu driver to figure out
> underlying whether this device has been attached to the domain
> with the said pasid.
> 
Yeah, I am checking the pasid matching in the iommu driver. My thinking is
that here is a quick sanity check in the common code to rule out invalid value.


Thanks a lot!


Jacob
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

  reply	other threads:[~2022-05-23 15:20 UTC|newest]

Thread overview: 70+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-18 18:21 [PATCH v4 0/6] Enable PASID for DMA API users Jacob Pan
2022-05-18 18:21 ` Jacob Pan
2022-05-18 18:21 ` [PATCH v4 1/6] iommu: Add a per domain PASID for DMA API Jacob Pan
2022-05-18 18:21   ` Jacob Pan
2022-05-19  6:50   ` Baolu Lu
2022-05-19  6:50     ` Baolu Lu
2022-05-24 13:50   ` Jason Gunthorpe
2022-05-24 13:50     ` Jason Gunthorpe via iommu
2022-05-24 15:17     ` Jacob Pan
2022-05-24 15:17       ` Jacob Pan
2022-05-30 12:22       ` Jason Gunthorpe
2022-05-30 12:22         ` Jason Gunthorpe via iommu
2022-05-31 10:12         ` Tian, Kevin
2022-05-31 10:12           ` Tian, Kevin
2022-05-31 12:45           ` Baolu Lu
2022-05-31 12:45             ` Baolu Lu
2022-05-31 16:03             ` Jason Gunthorpe
2022-05-31 16:03               ` Jason Gunthorpe via iommu
2022-05-31 17:29             ` Jacob Pan
2022-05-31 17:29               ` Jacob Pan
2022-05-31 19:05               ` Jason Gunthorpe
2022-05-31 19:05                 ` Jason Gunthorpe via iommu
2022-05-31 20:44                 ` Jacob Pan
2022-05-31 20:44                   ` Jacob Pan
2022-06-01  1:50                   ` Tian, Kevin
2022-06-01  1:50                     ` Tian, Kevin
2022-06-01  1:43               ` Tian, Kevin
2022-06-01  1:43                 ` Tian, Kevin
2022-06-01  9:37                 ` Baolu Lu
2022-06-01  9:37                   ` Baolu Lu
2022-06-01 10:05                   ` Tian, Kevin
2022-06-01 10:05                     ` Tian, Kevin
2022-05-18 18:21 ` [PATCH v4 2/6] iommu: Add a helper to do PASID lookup from domain Jacob Pan
2022-05-18 18:21   ` Jacob Pan
2022-05-19  6:41   ` Baolu Lu
2022-05-19  6:41     ` Baolu Lu
2022-05-19 20:10     ` Jacob Pan
2022-05-19 20:10       ` Jacob Pan
2022-05-19  6:48   ` Christoph Hellwig
2022-05-19  6:48     ` Christoph Hellwig
2022-05-20 15:18     ` Jacob Pan
2022-05-20 15:18       ` Jacob Pan
2022-05-23  7:55   ` Tian, Kevin
2022-05-23  7:55     ` Tian, Kevin
2022-05-23  9:14   ` Tian, Kevin
2022-05-23  9:14     ` Tian, Kevin
2022-05-23 18:01     ` Jacob Pan
2022-05-23 18:01       ` Jacob Pan
2022-05-18 18:21 ` [PATCH v4 3/6] iommu/vt-d: Implement domain ops for attach_dev_pasid Jacob Pan
2022-05-18 18:21   ` Jacob Pan
2022-05-24 13:51   ` Jason Gunthorpe
2022-05-24 13:51     ` Jason Gunthorpe via iommu
2022-05-24 16:12     ` Jacob Pan
2022-05-24 16:12       ` Jacob Pan
2022-05-24 18:02       ` Jason Gunthorpe
2022-05-24 18:02         ` Jason Gunthorpe via iommu
2022-05-24 20:45         ` Jacob Pan
2022-05-24 20:45           ` Jacob Pan
2022-05-24 21:10           ` Jason Gunthorpe
2022-05-24 21:10             ` Jason Gunthorpe via iommu
2022-05-18 18:21 ` [PATCH v4 4/6] iommu: Add PASID support for DMA mapping API users Jacob Pan
2022-05-18 18:21   ` Jacob Pan
2022-05-23  8:25   ` Tian, Kevin
2022-05-23  8:25     ` Tian, Kevin
2022-05-23 15:23     ` Jacob Pan [this message]
2022-05-23 15:23       ` Jacob Pan
2022-05-18 18:21 ` [PATCH v4 5/6] dmaengine: idxd: Use DMA API for in-kernel DMA with PASID Jacob Pan
2022-05-18 18:21   ` Jacob Pan
2022-05-18 18:21 ` [PATCH v4 6/6] iommu/vt-d: Delete unused SVM flag Jacob Pan
2022-05-18 18:21   ` 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=20220523082359.74fb435b@jacob-builder \
    --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=eric.auger@redhat.com \
    --cc=hch@infradead.org \
    --cc=iommu@lists.linux-foundation.org \
    --cc=jean-philippe@linaro.com \
    --cc=jgg@nvidia.com \
    --cc=joro@8bytes.org \
    --cc=kevin.tian@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=robin.murphy@arm.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.