Skip to content

Commit b3c9890

Browse files
hegdevasantjoergroedel
authored andcommitted
iommu/amd: Separate page table setup from domain allocation
Currently protection_domain_alloc() allocates domain and also sets up page table. Page table setup is required for PAGING domain only. Domain type like SVA doesn't need page table. Hence move page table setup code to separate function. Also SVA domain allocation path does not call pdom_setup_pgtable(). Hence remove IOMMU_DOMAIN_SVA type check. Signed-off-by: Vasant Hegde <[email protected]> Reviewed-by: Jacob Pan <[email protected]> Reviewed-by: Jason Gunthorpe <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent d15f55d commit b3c9890

File tree

1 file changed

+26
-16
lines changed

1 file changed

+26
-16
lines changed

drivers/iommu/amd/iommu.c

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2265,28 +2265,36 @@ void protection_domain_free(struct protection_domain *domain)
22652265

22662266
struct protection_domain *protection_domain_alloc(unsigned int type, int nid)
22672267
{
2268-
struct io_pgtable_ops *pgtbl_ops;
22692268
struct protection_domain *domain;
2270-
int pgtable;
22712269

22722270
domain = kzalloc(sizeof(*domain), GFP_KERNEL);
22732271
if (!domain)
22742272
return NULL;
22752273

22762274
domain->id = domain_id_alloc();
2277-
if (!domain->id)
2278-
goto err_free;
2275+
if (!domain->id) {
2276+
kfree(domain);
2277+
return NULL;
2278+
}
22792279

22802280
spin_lock_init(&domain->lock);
22812281
INIT_LIST_HEAD(&domain->dev_list);
22822282
INIT_LIST_HEAD(&domain->dev_data_list);
22832283
domain->iop.pgtbl.cfg.amd.nid = nid;
22842284

2285+
return domain;
2286+
}
2287+
2288+
static int pdom_setup_pgtable(struct protection_domain *domain,
2289+
unsigned int type)
2290+
{
2291+
struct io_pgtable_ops *pgtbl_ops;
2292+
int pgtable;
2293+
22852294
switch (type) {
22862295
/* No need to allocate io pgtable ops in passthrough mode */
22872296
case IOMMU_DOMAIN_IDENTITY:
2288-
case IOMMU_DOMAIN_SVA:
2289-
return domain;
2297+
return 0;
22902298
case IOMMU_DOMAIN_DMA:
22912299
pgtable = amd_iommu_pgtable;
22922300
break;
@@ -2298,7 +2306,7 @@ struct protection_domain *protection_domain_alloc(unsigned int type, int nid)
22982306
pgtable = AMD_IOMMU_V1;
22992307
break;
23002308
default:
2301-
goto err_id;
2309+
return -EINVAL;
23022310
}
23032311

23042312
switch (pgtable) {
@@ -2309,20 +2317,14 @@ struct protection_domain *protection_domain_alloc(unsigned int type, int nid)
23092317
domain->pd_mode = PD_MODE_V2;
23102318
break;
23112319
default:
2312-
goto err_id;
2320+
return -EINVAL;
23132321
}
2314-
23152322
pgtbl_ops =
23162323
alloc_io_pgtable_ops(pgtable, &domain->iop.pgtbl.cfg, domain);
23172324
if (!pgtbl_ops)
2318-
goto err_id;
2325+
return -ENOMEM;
23192326

2320-
return domain;
2321-
err_id:
2322-
domain_id_free(domain->id);
2323-
err_free:
2324-
kfree(domain);
2325-
return NULL;
2327+
return 0;
23262328
}
23272329

23282330
static inline u64 dma_max_address(void)
@@ -2345,6 +2347,7 @@ static struct iommu_domain *do_iommu_domain_alloc(unsigned int type,
23452347
bool dirty_tracking = flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
23462348
struct protection_domain *domain;
23472349
struct amd_iommu *iommu = NULL;
2350+
int ret;
23482351

23492352
if (dev)
23502353
iommu = get_amd_iommu_from_dev(dev);
@@ -2364,6 +2367,13 @@ static struct iommu_domain *do_iommu_domain_alloc(unsigned int type,
23642367
if (!domain)
23652368
return ERR_PTR(-ENOMEM);
23662369

2370+
ret = pdom_setup_pgtable(domain, type);
2371+
if (ret) {
2372+
domain_id_free(domain->id);
2373+
kfree(domain);
2374+
return ERR_PTR(ret);
2375+
}
2376+
23672377
domain->domain.geometry.aperture_start = 0;
23682378
domain->domain.geometry.aperture_end = dma_max_address();
23692379
domain->domain.geometry.force_aperture = true;

0 commit comments

Comments
 (0)