Skip to content

Commit addb665

Browse files
nicolincjgunthorpe
authored andcommitted
iommu: Introduce a new iommu_group_replace_domain() API
qemu has a need to replace the translations associated with a domain when the guest does large-scale operations like switching between an IDENTITY domain and, say, dma-iommu.c. Currently, it does this by replacing all the mappings in a single domain, but this is very inefficient and means that domains have to be per-device rather than per-translation. Provide a high-level API to allow replacements of one domain with another. This is similar to a detach/attach cycle except it doesn't force the group to go to the blocking domain in-between. By removing this forced blocking domain the iommu driver has the opportunity to implement a non-disruptive replacement of the domain to the greatest extent its hardware allows. This allows the qemu emulation of the vIOMMU to be more complete, as real hardware often has a non-distruptive replacement capability. It could be possible to address this by simply removing the protection from the iommu_attach_group(), but it is not so clear if that is safe for the few users. Thus, add a new API to serve this new purpose. All drivers are already required to support changing between active UNMANAGED domains when using their attach_dev ops. This API is expected to be used only by IOMMUFD, so add to the iommu-priv header and mark it as IOMMUFD_INTERNAL. Link: https://lore.kernel.org/r/13-v8-6659224517ea+532-iommufd_alloc_jgg@nvidia.com Suggested-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com> Tested-by: Nicolin Chen <nicolinc@nvidia.com> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
1 parent ea2d612 commit addb665

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

drivers/iommu/iommu-priv.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
#ifndef __LINUX_IOMMU_PRIV_H
3+
#define __LINUX_IOMMU_PRIV_H
4+
5+
#include <linux/iommu.h>
6+
7+
int iommu_group_replace_domain(struct iommu_group *group,
8+
struct iommu_domain *new_domain);
9+
10+
#endif /* __LINUX_IOMMU_PRIV_H */

drivers/iommu/iommu.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <linux/msi.h>
3535

3636
#include "dma-iommu.h"
37+
#include "iommu-priv.h"
3738

3839
#include "iommu-sva.h"
3940

@@ -2114,6 +2115,32 @@ int iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group)
21142115
}
21152116
EXPORT_SYMBOL_GPL(iommu_attach_group);
21162117

2118+
/**
2119+
* iommu_group_replace_domain - replace the domain that a group is attached to
2120+
* @new_domain: new IOMMU domain to replace with
2121+
* @group: IOMMU group that will be attached to the new domain
2122+
*
2123+
* This API allows the group to switch domains without being forced to go to
2124+
* the blocking domain in-between.
2125+
*
2126+
* If the currently attached domain is a core domain (e.g. a default_domain),
2127+
* it will act just like the iommu_attach_group().
2128+
*/
2129+
int iommu_group_replace_domain(struct iommu_group *group,
2130+
struct iommu_domain *new_domain)
2131+
{
2132+
int ret;
2133+
2134+
if (!new_domain)
2135+
return -EINVAL;
2136+
2137+
mutex_lock(&group->mutex);
2138+
ret = __iommu_group_set_domain(group, new_domain);
2139+
mutex_unlock(&group->mutex);
2140+
return ret;
2141+
}
2142+
EXPORT_SYMBOL_NS_GPL(iommu_group_replace_domain, IOMMUFD_INTERNAL);
2143+
21172144
static int __iommu_device_set_domain(struct iommu_group *group,
21182145
struct device *dev,
21192146
struct iommu_domain *new_domain,

0 commit comments

Comments
 (0)