mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-10 12:53:04 -04:00
iommu: Use __iommu_group_set_domain() for __iommu_attach_group()
The error recovery here matches the recovery inside __iommu_group_set_domain(), so just use it directly. Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com> Tested-by: Heiko Stuebner <heiko@sntech.de> Tested-by: Niklas Schnelle <schnelle@linux.ibm.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Link: https://lore.kernel.org/r/4-v5-1b99ae392328+44574-iommu_err_unwind_jgg@nvidia.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
committed by
Joerg Roedel
parent
dcf40ed3a2
commit
ecd60dc5d2
@@ -2159,52 +2159,14 @@ struct iommu_domain *iommu_get_dma_domain(struct device *dev)
|
||||
return dev->iommu_group->default_domain;
|
||||
}
|
||||
|
||||
/*
|
||||
* IOMMU groups are really the natural working unit of the IOMMU, but
|
||||
* the IOMMU API works on domains and devices. Bridge that gap by
|
||||
* iterating over the devices in a group. Ideally we'd have a single
|
||||
* device which represents the requestor ID of the group, but we also
|
||||
* allow IOMMU drivers to create policy defined minimum sets, where
|
||||
* the physical hardware may be able to distiguish members, but we
|
||||
* wish to group them at a higher level (ex. untrusted multi-function
|
||||
* PCI devices). Thus we attach each device.
|
||||
*/
|
||||
static int iommu_group_do_attach_device(struct device *dev, void *data)
|
||||
{
|
||||
struct iommu_domain *domain = data;
|
||||
|
||||
return __iommu_attach_device(domain, dev);
|
||||
}
|
||||
|
||||
static int __iommu_attach_group(struct iommu_domain *domain,
|
||||
struct iommu_group *group)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (group->domain && group->domain != group->default_domain &&
|
||||
group->domain != group->blocking_domain)
|
||||
return -EBUSY;
|
||||
|
||||
ret = __iommu_group_for_each_dev(group, domain,
|
||||
iommu_group_do_attach_device);
|
||||
if (ret == 0) {
|
||||
group->domain = domain;
|
||||
} else {
|
||||
/*
|
||||
* To recover from the case when certain device within the
|
||||
* group fails to attach to the new domain, we need force
|
||||
* attaching all devices back to the old domain. The old
|
||||
* domain is compatible for all devices in the group,
|
||||
* hence the iommu driver should always return success.
|
||||
*/
|
||||
struct iommu_domain *old_domain = group->domain;
|
||||
|
||||
group->domain = NULL;
|
||||
WARN(__iommu_group_set_domain(group, old_domain),
|
||||
"iommu driver failed to attach a compatible domain");
|
||||
}
|
||||
|
||||
return ret;
|
||||
return __iommu_group_set_domain(group, domain);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user