From: Lu Baolu <baolu.lu@linux.intel.com>
To: Joerg Roedel <joro@8bytes.org>,
Alex Williamson <alex.williamson@redhat.com>,
Robin Murphy <robin.murphy@arm.com>,
Jason Gunthorpe <jgg@nvidia.com>,
Christoph Hellwig <hch@infradead.org>,
Kevin Tian <kevin.tian@intel.com>,
Ashok Raj <ashok.raj@intel.com>
Cc: kvm@vger.kernel.org, rafael@kernel.org,
David Airlie <airlied@linux.ie>,
linux-pci@vger.kernel.org,
Thierry Reding <thierry.reding@gmail.com>,
Diana Craciun <diana.craciun@oss.nxp.com>,
Dmitry Osipenko <digetx@gmail.com>, Will Deacon <will@kernel.org>,
Stuart Yoder <stuyoder@gmail.com>,
Jonathan Hunter <jonathanh@nvidia.com>,
Chaitanya Kulkarni <kch@nvidia.com>,
Bjorn Helgaas <bhelgaas@google.com>,
Dan Williams <dan.j.williams@intel.com>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Cornelia Huck <cohuck@redhat.com>,
linux-kernel@vger.kernel.org, Li Yang <leoyang.li@nxp.com>,
iommu@lists.linux-foundation.org,
Jacob jun Pan <jacob.jun.pan@intel.com>,
Daniel Vetter <daniel@ffwll.ch>
Subject: [PATCH v1 3/8] iommu: Extend iommu_at[de]tach_device() for multi-device groups
Date: Thu, 6 Jan 2022 10:20:48 +0800 [thread overview]
Message-ID: <20220106022053.2406748-4-baolu.lu@linux.intel.com> (raw)
In-Reply-To: <20220106022053.2406748-1-baolu.lu@linux.intel.com>
The iommu_attach/detach_device() interfaces were exposed for the device
drivers to attach/detach their own domains. The commit <426a273834eae>
("iommu: Limit iommu_attach/detach_device to device with their own group")
restricted them to singleton groups to avoid different device in a group
attaching different domain.
As we've introduced device DMA ownership into the iommu core. We can now
extend these interfaces for muliple-device groups, and "all devices are in
the same address space" is still guaranteed.
For multiple devices belonging to a same group, iommu_device_use_dma_api()
and iommu_attach_device() are exclusive. Therefore, when drivers decide to
use iommu_attach_domain(), they cannot call iommu_device_use_dma_api() at
the same time.
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
drivers/iommu/iommu.c | 79 +++++++++++++++++++++++++++++++++----------
1 file changed, 62 insertions(+), 17 deletions(-)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index ab8ab95969f5..2c9efd85e447 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -47,6 +47,7 @@ struct iommu_group {
struct iommu_domain *domain;
struct list_head entry;
unsigned int owner_cnt;
+ unsigned int attach_cnt;
void *owner;
};
@@ -1921,27 +1922,59 @@ static int __iommu_attach_device(struct iommu_domain *domain,
return ret;
}
+/**
+ * iommu_attach_device() - attach external or UNMANAGED domain to device
+ * @domain: the domain about to attach
+ * @dev: the device about to be attached
+ *
+ * For devices belonging to the same group, iommu_device_use_dma_api() and
+ * iommu_attach_device() are exclusive. Therefore, when drivers decide to
+ * use iommu_attach_domain(), they cannot call iommu_device_use_dma_api()
+ * at the same time.
+ */
int iommu_attach_device(struct iommu_domain *domain, struct device *dev)
{
struct iommu_group *group;
- int ret;
+ int ret = 0;
+
+ if (domain->type != IOMMU_DOMAIN_UNMANAGED)
+ return -EINVAL;
group = iommu_group_get(dev);
if (!group)
return -ENODEV;
- /*
- * Lock the group to make sure the device-count doesn't
- * change while we are attaching
- */
mutex_lock(&group->mutex);
- ret = -EINVAL;
- if (iommu_group_device_count(group) != 1)
- goto out_unlock;
+ if (group->owner_cnt) {
+ /*
+ * Group has been used for kernel-api dma or claimed explicitly
+ * for exclusive occupation. For backward compatibility, device
+ * in a singleton group is allowed to ignore setting the
+ * drv.no_kernel_api_dma field.
+ */
+ if ((group->domain == group->default_domain &&
+ iommu_group_device_count(group) != 1) ||
+ group->owner) {
+ ret = -EBUSY;
+ goto unlock_out;
+ }
+ }
- ret = __iommu_attach_group(domain, group);
+ if (!group->attach_cnt) {
+ ret = __iommu_attach_group(domain, group);
+ if (ret)
+ goto unlock_out;
+ } else {
+ if (group->domain != domain) {
+ ret = -EPERM;
+ goto unlock_out;
+ }
+ }
-out_unlock:
+ group->owner_cnt++;
+ group->attach_cnt++;
+
+unlock_out:
mutex_unlock(&group->mutex);
iommu_group_put(group);
@@ -2182,23 +2215,35 @@ static void __iommu_detach_device(struct iommu_domain *domain,
trace_detach_device_from_domain(dev);
}
+/**
+ * iommu_detach_device() - detach external or UNMANAGED domain from device
+ * @domain: the domain about to detach
+ * @dev: the device about to be detached
+ *
+ * Paired with iommu_attach_device(), it detaches the domain from the device.
+ */
void iommu_detach_device(struct iommu_domain *domain, struct device *dev)
{
struct iommu_group *group;
+ if (WARN_ON(domain->type != IOMMU_DOMAIN_UNMANAGED))
+ return;
+
group = iommu_group_get(dev);
- if (!group)
+ if (WARN_ON(!group))
return;
mutex_lock(&group->mutex);
- if (iommu_group_device_count(group) != 1) {
- WARN_ON(1);
- goto out_unlock;
- }
+ if (WARN_ON(!group->attach_cnt || !group->owner_cnt ||
+ group->domain != domain))
+ goto unlock_out;
- __iommu_detach_group(domain, group);
+ group->attach_cnt--;
+ group->owner_cnt--;
+ if (!group->attach_cnt)
+ __iommu_detach_group(domain, group);
-out_unlock:
+unlock_out:
mutex_unlock(&group->mutex);
iommu_group_put(group);
}
--
2.25.1
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu
WARNING: multiple messages have this Message-ID (diff)
From: Lu Baolu <baolu.lu@linux.intel.com>
To: Joerg Roedel <joro@8bytes.org>,
Alex Williamson <alex.williamson@redhat.com>,
Robin Murphy <robin.murphy@arm.com>,
Jason Gunthorpe <jgg@nvidia.com>,
Christoph Hellwig <hch@infradead.org>,
Kevin Tian <kevin.tian@intel.com>,
Ashok Raj <ashok.raj@intel.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Bjorn Helgaas <bhelgaas@google.com>,
Will Deacon <will@kernel.org>,
Dan Williams <dan.j.williams@intel.com>,
rafael@kernel.org, Diana Craciun <diana.craciun@oss.nxp.com>,
Cornelia Huck <cohuck@redhat.com>,
Eric Auger <eric.auger@redhat.com>, Liu Yi L <yi.l.liu@intel.com>,
Jacob jun Pan <jacob.jun.pan@intel.com>,
Chaitanya Kulkarni <kch@nvidia.com>,
Stuart Yoder <stuyoder@gmail.com>,
Laurentiu Tudor <laurentiu.tudor@nxp.com>,
Thierry Reding <thierry.reding@gmail.com>,
David Airlie <airlied@linux.ie>, Daniel Vetter <daniel@ffwll.ch>,
Jonathan Hunter <jonathanh@nvidia.com>,
Li Yang <leoyang.li@nxp.com>, Dmitry Osipenko <digetx@gmail.com>,
iommu@lists.linux-foundation.org, linux-pci@vger.kernel.org,
kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
Lu Baolu <baolu.lu@linux.intel.com>
Subject: [PATCH v1 3/8] iommu: Extend iommu_at[de]tach_device() for multi-device groups
Date: Thu, 6 Jan 2022 10:20:48 +0800 [thread overview]
Message-ID: <20220106022053.2406748-4-baolu.lu@linux.intel.com> (raw)
In-Reply-To: <20220106022053.2406748-1-baolu.lu@linux.intel.com>
The iommu_attach/detach_device() interfaces were exposed for the device
drivers to attach/detach their own domains. The commit <426a273834eae>
("iommu: Limit iommu_attach/detach_device to device with their own group")
restricted them to singleton groups to avoid different device in a group
attaching different domain.
As we've introduced device DMA ownership into the iommu core. We can now
extend these interfaces for muliple-device groups, and "all devices are in
the same address space" is still guaranteed.
For multiple devices belonging to a same group, iommu_device_use_dma_api()
and iommu_attach_device() are exclusive. Therefore, when drivers decide to
use iommu_attach_domain(), they cannot call iommu_device_use_dma_api() at
the same time.
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
drivers/iommu/iommu.c | 79 +++++++++++++++++++++++++++++++++----------
1 file changed, 62 insertions(+), 17 deletions(-)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index ab8ab95969f5..2c9efd85e447 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -47,6 +47,7 @@ struct iommu_group {
struct iommu_domain *domain;
struct list_head entry;
unsigned int owner_cnt;
+ unsigned int attach_cnt;
void *owner;
};
@@ -1921,27 +1922,59 @@ static int __iommu_attach_device(struct iommu_domain *domain,
return ret;
}
+/**
+ * iommu_attach_device() - attach external or UNMANAGED domain to device
+ * @domain: the domain about to attach
+ * @dev: the device about to be attached
+ *
+ * For devices belonging to the same group, iommu_device_use_dma_api() and
+ * iommu_attach_device() are exclusive. Therefore, when drivers decide to
+ * use iommu_attach_domain(), they cannot call iommu_device_use_dma_api()
+ * at the same time.
+ */
int iommu_attach_device(struct iommu_domain *domain, struct device *dev)
{
struct iommu_group *group;
- int ret;
+ int ret = 0;
+
+ if (domain->type != IOMMU_DOMAIN_UNMANAGED)
+ return -EINVAL;
group = iommu_group_get(dev);
if (!group)
return -ENODEV;
- /*
- * Lock the group to make sure the device-count doesn't
- * change while we are attaching
- */
mutex_lock(&group->mutex);
- ret = -EINVAL;
- if (iommu_group_device_count(group) != 1)
- goto out_unlock;
+ if (group->owner_cnt) {
+ /*
+ * Group has been used for kernel-api dma or claimed explicitly
+ * for exclusive occupation. For backward compatibility, device
+ * in a singleton group is allowed to ignore setting the
+ * drv.no_kernel_api_dma field.
+ */
+ if ((group->domain == group->default_domain &&
+ iommu_group_device_count(group) != 1) ||
+ group->owner) {
+ ret = -EBUSY;
+ goto unlock_out;
+ }
+ }
- ret = __iommu_attach_group(domain, group);
+ if (!group->attach_cnt) {
+ ret = __iommu_attach_group(domain, group);
+ if (ret)
+ goto unlock_out;
+ } else {
+ if (group->domain != domain) {
+ ret = -EPERM;
+ goto unlock_out;
+ }
+ }
-out_unlock:
+ group->owner_cnt++;
+ group->attach_cnt++;
+
+unlock_out:
mutex_unlock(&group->mutex);
iommu_group_put(group);
@@ -2182,23 +2215,35 @@ static void __iommu_detach_device(struct iommu_domain *domain,
trace_detach_device_from_domain(dev);
}
+/**
+ * iommu_detach_device() - detach external or UNMANAGED domain from device
+ * @domain: the domain about to detach
+ * @dev: the device about to be detached
+ *
+ * Paired with iommu_attach_device(), it detaches the domain from the device.
+ */
void iommu_detach_device(struct iommu_domain *domain, struct device *dev)
{
struct iommu_group *group;
+ if (WARN_ON(domain->type != IOMMU_DOMAIN_UNMANAGED))
+ return;
+
group = iommu_group_get(dev);
- if (!group)
+ if (WARN_ON(!group))
return;
mutex_lock(&group->mutex);
- if (iommu_group_device_count(group) != 1) {
- WARN_ON(1);
- goto out_unlock;
- }
+ if (WARN_ON(!group->attach_cnt || !group->owner_cnt ||
+ group->domain != domain))
+ goto unlock_out;
- __iommu_detach_group(domain, group);
+ group->attach_cnt--;
+ group->owner_cnt--;
+ if (!group->attach_cnt)
+ __iommu_detach_group(domain, group);
-out_unlock:
+unlock_out:
mutex_unlock(&group->mutex);
iommu_group_put(group);
}
--
2.25.1
next prev parent reply other threads:[~2022-01-06 2:22 UTC|newest]
Thread overview: 88+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-06 2:20 [PATCH v1 0/8] Scrap iommu_attach/detach_group() interfaces Lu Baolu
2022-01-06 2:20 ` Lu Baolu
2022-01-06 2:20 ` [PATCH v1 1/8] iommu: Add iommu_group_replace_domain() Lu Baolu
2022-01-06 2:20 ` Lu Baolu
2022-01-06 17:06 ` Jason Gunthorpe via iommu
2022-01-06 17:06 ` Jason Gunthorpe
2022-01-07 0:26 ` Lu Baolu
2022-01-07 0:26 ` Lu Baolu
2022-02-14 12:09 ` Robin Murphy
2022-02-14 12:09 ` Robin Murphy
2022-02-14 12:45 ` Jason Gunthorpe via iommu
2022-02-14 12:45 ` Jason Gunthorpe
2022-02-14 14:10 ` Robin Murphy
2022-02-14 14:10 ` Robin Murphy
2022-02-14 14:56 ` Jason Gunthorpe via iommu
2022-02-14 14:56 ` Jason Gunthorpe
2022-02-14 16:38 ` Robin Murphy
2022-02-14 16:38 ` Robin Murphy
2022-02-14 17:25 ` Jason Gunthorpe via iommu
2022-02-14 17:25 ` Jason Gunthorpe
2022-01-06 2:20 ` [PATCH v1 2/8] vfio/type1: Use iommu_group_replace_domain() Lu Baolu
2022-01-06 2:20 ` Lu Baolu
2022-01-06 2:20 ` Lu Baolu [this message]
2022-01-06 2:20 ` [PATCH v1 3/8] iommu: Extend iommu_at[de]tach_device() for multi-device groups Lu Baolu
2022-01-06 17:22 ` Jason Gunthorpe via iommu
2022-01-06 17:22 ` Jason Gunthorpe
2022-01-07 1:14 ` Lu Baolu
2022-01-07 1:14 ` Lu Baolu
2022-01-07 1:19 ` Jason Gunthorpe via iommu
2022-01-07 1:19 ` Jason Gunthorpe
2022-02-14 11:39 ` Joerg Roedel
2022-02-14 11:39 ` Joerg Roedel
2022-02-14 13:03 ` Jason Gunthorpe via iommu
2022-02-14 13:03 ` Jason Gunthorpe
2022-02-14 14:39 ` Joerg Roedel
2022-02-14 14:39 ` Joerg Roedel
2022-02-14 15:18 ` Robin Murphy
2022-02-14 15:18 ` Robin Murphy
2022-02-14 15:46 ` Jason Gunthorpe via iommu
2022-02-14 15:46 ` Jason Gunthorpe
2022-02-15 8:58 ` Joerg Roedel
2022-02-15 8:58 ` Joerg Roedel
2022-02-15 13:47 ` Jason Gunthorpe via iommu
2022-02-15 13:47 ` Jason Gunthorpe
2022-02-16 6:28 ` Lu Baolu
2022-02-16 6:28 ` Lu Baolu
2022-02-16 13:54 ` Jason Gunthorpe via iommu
2022-02-16 13:54 ` Jason Gunthorpe
2022-01-06 2:20 ` [PATCH v1 4/8] drm/tegra: Use iommu_attach/detatch_device() Lu Baolu
2022-01-06 2:20 ` Lu Baolu
2022-01-06 2:20 ` [PATCH v1 5/8] iommu/amd: Use iommu_attach/detach_device() Lu Baolu
2022-01-06 2:20 ` Lu Baolu
2022-01-06 14:33 ` Jason Gunthorpe via iommu
2022-01-06 14:33 ` Jason Gunthorpe
2022-01-07 0:23 ` Lu Baolu
2022-01-07 0:23 ` Lu Baolu
2022-02-14 11:27 ` Joerg Roedel
2022-02-14 11:27 ` Joerg Roedel
2022-02-14 13:15 ` Jason Gunthorpe via iommu
2022-02-14 13:15 ` Jason Gunthorpe
2022-02-14 13:40 ` Joerg Roedel
2022-02-14 13:40 ` Joerg Roedel
2022-02-14 14:02 ` Jason Gunthorpe via iommu
2022-02-14 14:02 ` Jason Gunthorpe
2022-02-14 14:23 ` Joerg Roedel
2022-02-14 14:23 ` Joerg Roedel
2022-02-14 15:00 ` Jason Gunthorpe via iommu
2022-02-14 15:00 ` Jason Gunthorpe
2022-02-15 9:11 ` Joerg Roedel
2022-02-15 9:11 ` Joerg Roedel
2022-02-15 13:02 ` Robin Murphy
2022-02-15 13:02 ` Robin Murphy
2022-02-15 14:37 ` Jason Gunthorpe via iommu
2022-02-15 14:37 ` Jason Gunthorpe
2022-01-06 2:20 ` [PATCH v1 6/8] gpu/host1x: " Lu Baolu
2022-01-06 2:20 ` Lu Baolu
2022-01-06 15:35 ` Jason Gunthorpe via iommu
2022-01-06 15:35 ` Jason Gunthorpe
2022-01-07 0:35 ` Lu Baolu
2022-01-07 0:35 ` Lu Baolu
2022-01-07 0:48 ` Jason Gunthorpe via iommu
2022-01-07 0:48 ` Jason Gunthorpe
2022-01-07 1:19 ` Lu Baolu
2022-01-07 1:19 ` Lu Baolu
2022-01-06 2:20 ` [PATCH v1 7/8] media: staging: media: tegra-vde: " Lu Baolu
2022-01-06 2:20 ` Lu Baolu
2022-01-06 2:20 ` [PATCH v1 8/8] iommu: Remove iommu_attach/detach_group() Lu Baolu
2022-01-06 2:20 ` Lu Baolu
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=20220106022053.2406748-4-baolu.lu@linux.intel.com \
--to=baolu.lu@linux.intel.com \
--cc=airlied@linux.ie \
--cc=alex.williamson@redhat.com \
--cc=ashok.raj@intel.com \
--cc=bhelgaas@google.com \
--cc=cohuck@redhat.com \
--cc=dan.j.williams@intel.com \
--cc=daniel@ffwll.ch \
--cc=diana.craciun@oss.nxp.com \
--cc=digetx@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=hch@infradead.org \
--cc=iommu@lists.linux-foundation.org \
--cc=jacob.jun.pan@intel.com \
--cc=jgg@nvidia.com \
--cc=jonathanh@nvidia.com \
--cc=joro@8bytes.org \
--cc=kch@nvidia.com \
--cc=kevin.tian@intel.com \
--cc=kvm@vger.kernel.org \
--cc=leoyang.li@nxp.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=rafael@kernel.org \
--cc=robin.murphy@arm.com \
--cc=stuyoder@gmail.com \
--cc=thierry.reding@gmail.com \
--cc=will@kernel.org \
/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.