Skip to content

Commit 0286300

Browse files
Jason Gunthorpe via iommujoergroedel
authored andcommitted
iommu: iommu_group_claim_dma_owner() must always assign a domain
Once the group enters 'owned' mode it can never be assigned back to the default_domain or to a NULL domain. It must always be actively assigned to a current domain. If the caller hasn't provided a domain then the core must provide an explicit DMA blocking domain that has no DMA map. Lazily create a group-global blocking DMA domain when iommu_group_claim_dma_owner is first called and immediately assign the group to it. This ensures that DMA is immediately fully isolated on all IOMMU drivers. If the user attaches/detaches while owned then detach will set the group back to the blocking domain. Slightly reorganize the call chains so that __iommu_group_set_core_domain() is the function that removes any caller configured domain and sets the domains back a core owned domain with an appropriate lifetime. __iommu_group_set_domain() is the worker function that can change the domain assigned to a group to any target domain, including NULL. Add comments clarifying how the NULL vs detach_dev vs default_domain works based on Robin's remarks. This fixes an oops with VFIO and SMMUv3 because VFIO will call iommu_detach_group() and then immediately iommu_domain_free(), but SMMUv3 has no way to know that the domain it is holding a pointer to has been freed. Now the iommu_detach_group() will assign the blocking domain and SMMUv3 will no longer hold a stale domain reference. Fixes: 1ea2a07 ("iommu: Add DMA ownership management interfaces") Reported-by: Qian Cai <[email protected]> Tested-by: Baolu Lu <[email protected]> Tested-by: Nicolin Chen <[email protected]> Co-developed-by: Robin Murphy <[email protected]> Signed-off-by: Robin Murphy <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]> -- Just minor polishing as discussed v3: - Change names to __iommu_group_set_domain() / __iommu_group_set_core_domain() - Clarify comments - Call __iommu_group_set_domain() directly in iommu_group_release_dma_owner() since we know it is always selecting the default_domain - Remove redundant detach_dev ops check in __iommu_detach_device and make the added WARN_ON fail instead - Check for blocking_domain in __iommu_attach_group() so VFIO can actually attach a new group - Update comments and spelling - Fix missed change to new_domain in iommu_group_do_detach_device() v2: https://lore.kernel.org/r/[email protected] v1: https://lore.kernel.org/r/[email protected] Reviewed-by: Kevin Tian <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent a5f1bd1 commit 0286300

File tree

1 file changed

+91
-36
lines changed

1 file changed

+91
-36
lines changed

drivers/iommu/iommu.c

Lines changed: 91 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ struct iommu_group {
4444
char *name;
4545
int id;
4646
struct iommu_domain *default_domain;
47+
struct iommu_domain *blocking_domain;
4748
struct iommu_domain *domain;
4849
struct list_head entry;
4950
unsigned int owner_cnt;
@@ -82,8 +83,8 @@ static int __iommu_attach_device(struct iommu_domain *domain,
8283
struct device *dev);
8384
static int __iommu_attach_group(struct iommu_domain *domain,
8485
struct iommu_group *group);
85-
static void __iommu_detach_group(struct iommu_domain *domain,
86-
struct iommu_group *group);
86+
static int __iommu_group_set_domain(struct iommu_group *group,
87+
struct iommu_domain *new_domain);
8788
static int iommu_create_device_direct_mappings(struct iommu_group *group,
8889
struct device *dev);
8990
static struct iommu_group *iommu_group_get_for_dev(struct device *dev);
@@ -596,6 +597,8 @@ static void iommu_group_release(struct kobject *kobj)
596597

597598
if (group->default_domain)
598599
iommu_domain_free(group->default_domain);
600+
if (group->blocking_domain)
601+
iommu_domain_free(group->blocking_domain);
599602

600603
kfree(group->name);
601604
kfree(group);
@@ -1907,6 +1910,24 @@ void iommu_domain_free(struct iommu_domain *domain)
19071910
}
19081911
EXPORT_SYMBOL_GPL(iommu_domain_free);
19091912

1913+
/*
1914+
* Put the group's domain back to the appropriate core-owned domain - either the
1915+
* standard kernel-mode DMA configuration or an all-DMA-blocked domain.
1916+
*/
1917+
static void __iommu_group_set_core_domain(struct iommu_group *group)
1918+
{
1919+
struct iommu_domain *new_domain;
1920+
int ret;
1921+
1922+
if (group->owner)
1923+
new_domain = group->blocking_domain;
1924+
else
1925+
new_domain = group->default_domain;
1926+
1927+
ret = __iommu_group_set_domain(group, new_domain);
1928+
WARN(ret, "iommu driver failed to attach the default/blocking domain");
1929+
}
1930+
19101931
static int __iommu_attach_device(struct iommu_domain *domain,
19111932
struct device *dev)
19121933
{
@@ -1963,9 +1984,6 @@ static void __iommu_detach_device(struct iommu_domain *domain,
19631984
if (iommu_is_attach_deferred(dev))
19641985
return;
19651986

1966-
if (unlikely(domain->ops->detach_dev == NULL))
1967-
return;
1968-
19691987
domain->ops->detach_dev(domain, dev);
19701988
trace_detach_device_from_domain(dev);
19711989
}
@@ -1979,12 +1997,10 @@ void iommu_detach_device(struct iommu_domain *domain, struct device *dev)
19791997
return;
19801998

19811999
mutex_lock(&group->mutex);
1982-
if (iommu_group_device_count(group) != 1) {
1983-
WARN_ON(1);
2000+
if (WARN_ON(domain != group->domain) ||
2001+
WARN_ON(iommu_group_device_count(group) != 1))
19842002
goto out_unlock;
1985-
}
1986-
1987-
__iommu_detach_group(domain, group);
2003+
__iommu_group_set_core_domain(group);
19882004

19892005
out_unlock:
19902006
mutex_unlock(&group->mutex);
@@ -2040,7 +2056,8 @@ static int __iommu_attach_group(struct iommu_domain *domain,
20402056
{
20412057
int ret;
20422058

2043-
if (group->domain && group->domain != group->default_domain)
2059+
if (group->domain && group->domain != group->default_domain &&
2060+
group->domain != group->blocking_domain)
20442061
return -EBUSY;
20452062

20462063
ret = __iommu_group_for_each_dev(group, domain,
@@ -2072,38 +2089,49 @@ static int iommu_group_do_detach_device(struct device *dev, void *data)
20722089
return 0;
20732090
}
20742091

2075-
static void __iommu_detach_group(struct iommu_domain *domain,
2076-
struct iommu_group *group)
2092+
static int __iommu_group_set_domain(struct iommu_group *group,
2093+
struct iommu_domain *new_domain)
20772094
{
20782095
int ret;
20792096

2097+
if (group->domain == new_domain)
2098+
return 0;
2099+
20802100
/*
2081-
* If the group has been claimed already, do not re-attach the default
2082-
* domain.
2101+
* New drivers should support default domains and so the detach_dev() op
2102+
* will never be called. Otherwise the NULL domain represents some
2103+
* platform specific behavior.
20832104
*/
2084-
if (!group->default_domain || group->owner) {
2085-
__iommu_group_for_each_dev(group, domain,
2105+
if (!new_domain) {
2106+
if (WARN_ON(!group->domain->ops->detach_dev))
2107+
return -EINVAL;
2108+
__iommu_group_for_each_dev(group, group->domain,
20862109
iommu_group_do_detach_device);
20872110
group->domain = NULL;
2088-
return;
2111+
return 0;
20892112
}
20902113

2091-
if (group->domain == group->default_domain)
2092-
return;
2093-
2094-
/* Detach by re-attaching to the default domain */
2095-
ret = __iommu_group_for_each_dev(group, group->default_domain,
2114+
/*
2115+
* Changing the domain is done by calling attach_dev() on the new
2116+
* domain. This switch does not have to be atomic and DMA can be
2117+
* discarded during the transition. DMA must only be able to access
2118+
* either new_domain or group->domain, never something else.
2119+
*
2120+
* Note that this is called in error unwind paths, attaching to a
2121+
* domain that has already been attached cannot fail.
2122+
*/
2123+
ret = __iommu_group_for_each_dev(group, new_domain,
20962124
iommu_group_do_attach_device);
2097-
if (ret != 0)
2098-
WARN_ON(1);
2099-
else
2100-
group->domain = group->default_domain;
2125+
if (ret)
2126+
return ret;
2127+
group->domain = new_domain;
2128+
return 0;
21012129
}
21022130

21032131
void iommu_detach_group(struct iommu_domain *domain, struct iommu_group *group)
21042132
{
21052133
mutex_lock(&group->mutex);
2106-
__iommu_detach_group(domain, group);
2134+
__iommu_group_set_core_domain(group);
21072135
mutex_unlock(&group->mutex);
21082136
}
21092137
EXPORT_SYMBOL_GPL(iommu_detach_group);
@@ -3088,6 +3116,29 @@ void iommu_device_unuse_default_domain(struct device *dev)
30883116
iommu_group_put(group);
30893117
}
30903118

3119+
static int __iommu_group_alloc_blocking_domain(struct iommu_group *group)
3120+
{
3121+
struct group_device *dev =
3122+
list_first_entry(&group->devices, struct group_device, list);
3123+
3124+
if (group->blocking_domain)
3125+
return 0;
3126+
3127+
group->blocking_domain =
3128+
__iommu_domain_alloc(dev->dev->bus, IOMMU_DOMAIN_BLOCKED);
3129+
if (!group->blocking_domain) {
3130+
/*
3131+
* For drivers that do not yet understand IOMMU_DOMAIN_BLOCKED
3132+
* create an empty domain instead.
3133+
*/
3134+
group->blocking_domain = __iommu_domain_alloc(
3135+
dev->dev->bus, IOMMU_DOMAIN_UNMANAGED);
3136+
if (!group->blocking_domain)
3137+
return -EINVAL;
3138+
}
3139+
return 0;
3140+
}
3141+
30913142
/**
30923143
* iommu_group_claim_dma_owner() - Set DMA ownership of a group
30933144
* @group: The group.
@@ -3111,9 +3162,14 @@ int iommu_group_claim_dma_owner(struct iommu_group *group, void *owner)
31113162
goto unlock_out;
31123163
}
31133164

3165+
ret = __iommu_group_alloc_blocking_domain(group);
3166+
if (ret)
3167+
goto unlock_out;
3168+
3169+
ret = __iommu_group_set_domain(group, group->blocking_domain);
3170+
if (ret)
3171+
goto unlock_out;
31143172
group->owner = owner;
3115-
if (group->domain)
3116-
__iommu_detach_group(group->domain, group);
31173173
}
31183174

31193175
group->owner_cnt++;
@@ -3132,18 +3188,17 @@ EXPORT_SYMBOL_GPL(iommu_group_claim_dma_owner);
31323188
*/
31333189
void iommu_group_release_dma_owner(struct iommu_group *group)
31343190
{
3191+
int ret;
3192+
31353193
mutex_lock(&group->mutex);
31363194
if (WARN_ON(!group->owner_cnt || !group->owner))
31373195
goto unlock_out;
31383196

31393197
group->owner_cnt = 0;
3140-
/*
3141-
* The UNMANAGED domain should be detached before all USER
3142-
* owners have been released.
3143-
*/
3144-
if (!WARN_ON(group->domain) && group->default_domain)
3145-
__iommu_attach_group(group->default_domain, group);
31463198
group->owner = NULL;
3199+
ret = __iommu_group_set_domain(group, group->default_domain);
3200+
WARN(ret, "iommu driver failed to attach the default domain");
3201+
31473202
unlock_out:
31483203
mutex_unlock(&group->mutex);
31493204
}

0 commit comments

Comments
 (0)