Skip to content

Commit 34e2dcc

Browse files
jgunthorpejoergroedel
authored andcommitted
iommu: Flow ERR_PTR out from __iommu_domain_alloc()
Most of the calling code now has error handling that can carry an error code further up the call chain. Keep the exported interface iommu_domain_alloc() returning NULL and reflow the internal code to use ERR_PTR not NULL for domain allocation failure. Optionally allow drivers to return ERR_PTR from any of the alloc ops. Many of the new ops (user, sva, etc) already return ERR_PTR, so having two rules is confusing and hard on drivers. This fixes a bug in DART that was returning ERR_PTR. Fixes: 482feb5 ("iommu/dart: Call apple_dart_finalize_domain() as part of alloc_paging()") Reported-by: Dan Carpenter <[email protected]> Link: https://lore.kernel.org/linux-iommu/[email protected]/ Signed-off-by: Jason Gunthorpe <[email protected]> Reviewed-by: Jerry Snitselaar <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent 2cc14f5 commit 34e2dcc

File tree

1 file changed

+39
-20
lines changed

1 file changed

+39
-20
lines changed

drivers/iommu/iommu.c

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1788,7 +1788,7 @@ iommu_group_alloc_default_domain(struct iommu_group *group, int req_type)
17881788
*/
17891789
if (ops->default_domain) {
17901790
if (req_type)
1791-
return NULL;
1791+
return ERR_PTR(-EINVAL);
17921792
return ops->default_domain;
17931793
}
17941794

@@ -1797,15 +1797,15 @@ iommu_group_alloc_default_domain(struct iommu_group *group, int req_type)
17971797

17981798
/* The driver gave no guidance on what type to use, try the default */
17991799
dom = __iommu_group_alloc_default_domain(group, iommu_def_domain_type);
1800-
if (dom)
1800+
if (!IS_ERR(dom))
18011801
return dom;
18021802

18031803
/* Otherwise IDENTITY and DMA_FQ defaults will try DMA */
18041804
if (iommu_def_domain_type == IOMMU_DOMAIN_DMA)
1805-
return NULL;
1805+
return ERR_PTR(-EINVAL);
18061806
dom = __iommu_group_alloc_default_domain(group, IOMMU_DOMAIN_DMA);
1807-
if (!dom)
1808-
return NULL;
1807+
if (IS_ERR(dom))
1808+
return dom;
18091809

18101810
pr_warn("Failed to allocate default IOMMU domain of type %u for group %s - Falling back to IOMMU_DOMAIN_DMA",
18111811
iommu_def_domain_type, group->name);
@@ -2094,10 +2094,17 @@ static struct iommu_domain *__iommu_domain_alloc(const struct iommu_ops *ops,
20942094
else if (ops->domain_alloc)
20952095
domain = ops->domain_alloc(alloc_type);
20962096
else
2097-
return NULL;
2097+
return ERR_PTR(-EOPNOTSUPP);
20982098

2099+
/*
2100+
* Many domain_alloc ops now return ERR_PTR, make things easier for the
2101+
* driver by accepting ERR_PTR from all domain_alloc ops instead of
2102+
* having two rules.
2103+
*/
2104+
if (IS_ERR(domain))
2105+
return domain;
20992106
if (!domain)
2100-
return NULL;
2107+
return ERR_PTR(-ENOMEM);
21012108

21022109
domain->type = type;
21032110
/*
@@ -2110,9 +2117,14 @@ static struct iommu_domain *__iommu_domain_alloc(const struct iommu_ops *ops,
21102117
if (!domain->ops)
21112118
domain->ops = ops->default_domain_ops;
21122119

2113-
if (iommu_is_dma_domain(domain) && iommu_get_dma_cookie(domain)) {
2114-
iommu_domain_free(domain);
2115-
domain = NULL;
2120+
if (iommu_is_dma_domain(domain)) {
2121+
int rc;
2122+
2123+
rc = iommu_get_dma_cookie(domain);
2124+
if (rc) {
2125+
iommu_domain_free(domain);
2126+
return ERR_PTR(rc);
2127+
}
21162128
}
21172129
return domain;
21182130
}
@@ -2129,10 +2141,15 @@ __iommu_group_domain_alloc(struct iommu_group *group, unsigned int type)
21292141

21302142
struct iommu_domain *iommu_domain_alloc(const struct bus_type *bus)
21312143
{
2144+
struct iommu_domain *domain;
2145+
21322146
if (bus == NULL || bus->iommu_ops == NULL)
21332147
return NULL;
2134-
return __iommu_domain_alloc(bus->iommu_ops, NULL,
2148+
domain = __iommu_domain_alloc(bus->iommu_ops, NULL,
21352149
IOMMU_DOMAIN_UNMANAGED);
2150+
if (IS_ERR(domain))
2151+
return NULL;
2152+
return domain;
21362153
}
21372154
EXPORT_SYMBOL_GPL(iommu_domain_alloc);
21382155

@@ -3041,8 +3058,8 @@ static int iommu_setup_default_domain(struct iommu_group *group,
30413058
return -EINVAL;
30423059

30433060
dom = iommu_group_alloc_default_domain(group, req_type);
3044-
if (!dom)
3045-
return -ENODEV;
3061+
if (IS_ERR(dom))
3062+
return PTR_ERR(dom);
30463063

30473064
if (group->default_domain == dom)
30483065
return 0;
@@ -3243,21 +3260,23 @@ void iommu_device_unuse_default_domain(struct device *dev)
32433260

32443261
static int __iommu_group_alloc_blocking_domain(struct iommu_group *group)
32453262
{
3263+
struct iommu_domain *domain;
3264+
32463265
if (group->blocking_domain)
32473266
return 0;
32483267

3249-
group->blocking_domain =
3250-
__iommu_group_domain_alloc(group, IOMMU_DOMAIN_BLOCKED);
3251-
if (!group->blocking_domain) {
3268+
domain = __iommu_group_domain_alloc(group, IOMMU_DOMAIN_BLOCKED);
3269+
if (IS_ERR(domain)) {
32523270
/*
32533271
* For drivers that do not yet understand IOMMU_DOMAIN_BLOCKED
32543272
* create an empty domain instead.
32553273
*/
3256-
group->blocking_domain = __iommu_group_domain_alloc(
3257-
group, IOMMU_DOMAIN_UNMANAGED);
3258-
if (!group->blocking_domain)
3259-
return -EINVAL;
3274+
domain = __iommu_group_domain_alloc(group,
3275+
IOMMU_DOMAIN_UNMANAGED);
3276+
if (IS_ERR(domain))
3277+
return PTR_ERR(domain);
32603278
}
3279+
group->blocking_domain = domain;
32613280
return 0;
32623281
}
32633282

0 commit comments

Comments
 (0)