Skip to content

Commit 45677ab

Browse files
ssuthiku-amdjoergroedel
authored andcommitted
iommu/amd: Miscellaneous clean up when free domain
* Use the protection_domain_free() helper function to free domain. The function has been modified to also free memory used for the v1 and v2 page tables. Also clear gcr3 table in v2 page table free path. * Refactor code into cleanup_domain() for reusability. Change BUG_ON to WARN_ON in cleanup path. * Protection domain dev_cnt should be read when the domain is locked. Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> Co-developed-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Vasant Hegde <vasant.hegde@amd.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com> Link: https://lore.kernel.org/r/20230921092147.5930-8-vasant.hegde@amd.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
1 parent 4c721d6 commit 45677ab

File tree

2 files changed

+26
-26
lines changed

2 files changed

+26
-26
lines changed

drivers/iommu/amd/io_pgtable_v2.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -363,10 +363,10 @@ static void v2_free_pgtable(struct io_pgtable *iop)
363363
if (!(pdom->flags & PD_IOMMUV2_MASK))
364364
return;
365365

366-
/*
367-
* Make changes visible to IOMMUs. No need to clear gcr3 entry
368-
* as gcr3 table is already freed.
369-
*/
366+
/* Clear gcr3 entry */
367+
amd_iommu_domain_clear_gcr3(&pdom->domain, 0);
368+
369+
/* Make changes visible to IOMMUs */
370370
amd_iommu_domain_update(pdom);
371371

372372
/* Free page table */

drivers/iommu/amd/iommu.c

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2047,18 +2047,19 @@ void amd_iommu_domain_update(struct protection_domain *domain)
20472047
static void cleanup_domain(struct protection_domain *domain)
20482048
{
20492049
struct iommu_dev_data *entry;
2050-
unsigned long flags;
20512050

2052-
spin_lock_irqsave(&domain->lock, flags);
2051+
lockdep_assert_held(&domain->lock);
2052+
2053+
if (!domain->dev_cnt)
2054+
return;
20532055

20542056
while (!list_empty(&domain->dev_list)) {
20552057
entry = list_first_entry(&domain->dev_list,
20562058
struct iommu_dev_data, list);
20572059
BUG_ON(!entry->domain);
20582060
do_detach(entry);
20592061
}
2060-
2061-
spin_unlock_irqrestore(&domain->lock, flags);
2062+
WARN_ON(domain->dev_cnt != 0);
20622063
}
20632064

20642065
static void protection_domain_free(struct protection_domain *domain)
@@ -2069,6 +2070,12 @@ static void protection_domain_free(struct protection_domain *domain)
20692070
if (domain->iop.pgtbl_cfg.tlb)
20702071
free_io_pgtable_ops(&domain->iop.iop.ops);
20712072

2073+
if (domain->flags & PD_IOMMUV2_MASK)
2074+
free_gcr3_table(domain);
2075+
2076+
if (domain->iop.root)
2077+
free_page((unsigned long)domain->iop.root);
2078+
20722079
if (domain->id)
20732080
domain_id_free(domain->id);
20742081

@@ -2083,10 +2090,8 @@ static int protection_domain_init_v1(struct protection_domain *domain, int mode)
20832090

20842091
if (mode != PAGE_MODE_NONE) {
20852092
pt_root = (void *)get_zeroed_page(GFP_KERNEL);
2086-
if (!pt_root) {
2087-
domain_id_free(domain->id);
2093+
if (!pt_root)
20882094
return -ENOMEM;
2089-
}
20902095
}
20912096

20922097
amd_iommu_domain_set_pgtable(domain, pt_root, mode);
@@ -2100,10 +2105,8 @@ static int protection_domain_init_v2(struct protection_domain *domain)
21002105

21012106
domain->domain.pgsize_bitmap = AMD_IOMMU_PGSIZES_V2;
21022107

2103-
if (setup_gcr3_table(domain, 1)) {
2104-
domain_id_free(domain->id);
2108+
if (setup_gcr3_table(domain, 1))
21052109
return -ENOMEM;
2106-
}
21072110

21082111
return 0;
21092112
}
@@ -2162,14 +2165,12 @@ static struct protection_domain *protection_domain_alloc(unsigned int type)
21622165
goto out_err;
21632166

21642167
pgtbl_ops = alloc_io_pgtable_ops(pgtable, &domain->iop.pgtbl_cfg, domain);
2165-
if (!pgtbl_ops) {
2166-
domain_id_free(domain->id);
2168+
if (!pgtbl_ops)
21672169
goto out_err;
2168-
}
21692170

21702171
return domain;
21712172
out_err:
2172-
kfree(domain);
2173+
protection_domain_free(domain);
21732174
return NULL;
21742175
}
21752176

@@ -2207,19 +2208,18 @@ static struct iommu_domain *amd_iommu_domain_alloc(unsigned type)
22072208
static void amd_iommu_domain_free(struct iommu_domain *dom)
22082209
{
22092210
struct protection_domain *domain;
2211+
unsigned long flags;
22102212

2211-
domain = to_pdomain(dom);
2213+
if (!dom)
2214+
return;
22122215

2213-
if (domain->dev_cnt > 0)
2214-
cleanup_domain(domain);
2216+
domain = to_pdomain(dom);
22152217

2216-
BUG_ON(domain->dev_cnt != 0);
2218+
spin_lock_irqsave(&domain->lock, flags);
22172219

2218-
if (!dom)
2219-
return;
2220+
cleanup_domain(domain);
22202221

2221-
if (domain->flags & PD_IOMMUV2_MASK)
2222-
free_gcr3_table(domain);
2222+
spin_unlock_irqrestore(&domain->lock, flags);
22232223

22242224
protection_domain_free(domain);
22252225
}

0 commit comments

Comments
 (0)