Skip to content

Commit 43312b7

Browse files
ssuthiku-amdjoergroedel
authored andcommitted
iommu/amd: Refactor amd_iommu_domain_enable_v2 to remove locking
The current function to enable IOMMU v2 also lock the domain. In order to reuse the same code in different code path, in which the domain has already been locked, refactor the function to separate the locking from the enabling logic. Co-developed-by: Vasant Hegde <[email protected]> Signed-off-by: Vasant Hegde <[email protected]> Signed-off-by: Suravee Suthikulpanit <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent 6b080c4 commit 43312b7

File tree

1 file changed

+27
-19
lines changed

1 file changed

+27
-19
lines changed

drivers/iommu/amd/iommu.c

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ struct iommu_cmd {
8585
struct kmem_cache *amd_iommu_irq_cache;
8686

8787
static void detach_device(struct device *dev);
88+
static int domain_enable_v2(struct protection_domain *domain, int pasids);
8889

8990
/****************************************************************************
9091
*
@@ -2450,11 +2451,10 @@ void amd_iommu_domain_direct_map(struct iommu_domain *dom)
24502451
}
24512452
EXPORT_SYMBOL(amd_iommu_domain_direct_map);
24522453

2453-
int amd_iommu_domain_enable_v2(struct iommu_domain *dom, int pasids)
2454+
/* Note: This function expects iommu_domain->lock to be held prior calling the function. */
2455+
static int domain_enable_v2(struct protection_domain *domain, int pasids)
24542456
{
2455-
struct protection_domain *domain = to_pdomain(dom);
2456-
unsigned long flags;
2457-
int levels, ret;
2457+
int levels;
24582458

24592459
/* Number of GCR3 table levels required */
24602460
for (levels = 0; (pasids - 1) & ~0x1ff; pasids >>= 9)
@@ -2463,32 +2463,40 @@ int amd_iommu_domain_enable_v2(struct iommu_domain *dom, int pasids)
24632463
if (levels > amd_iommu_max_glx_val)
24642464
return -EINVAL;
24652465

2466-
spin_lock_irqsave(&domain->lock, flags);
2466+
domain->gcr3_tbl = (void *)get_zeroed_page(GFP_ATOMIC);
2467+
if (domain->gcr3_tbl == NULL)
2468+
return -ENOMEM;
2469+
2470+
domain->glx = levels;
2471+
domain->flags |= PD_IOMMUV2_MASK;
2472+
2473+
amd_iommu_domain_update(domain);
2474+
2475+
return 0;
2476+
}
2477+
2478+
int amd_iommu_domain_enable_v2(struct iommu_domain *dom, int pasids)
2479+
{
2480+
struct protection_domain *pdom = to_pdomain(dom);
2481+
unsigned long flags;
2482+
int ret;
2483+
2484+
spin_lock_irqsave(&pdom->lock, flags);
24672485

24682486
/*
24692487
* Save us all sanity checks whether devices already in the
24702488
* domain support IOMMUv2. Just force that the domain has no
24712489
* devices attached when it is switched into IOMMUv2 mode.
24722490
*/
24732491
ret = -EBUSY;
2474-
if (domain->dev_cnt > 0 || domain->flags & PD_IOMMUV2_MASK)
2475-
goto out;
2476-
2477-
ret = -ENOMEM;
2478-
domain->gcr3_tbl = (void *)get_zeroed_page(GFP_ATOMIC);
2479-
if (domain->gcr3_tbl == NULL)
2492+
if (pdom->dev_cnt > 0 || pdom->flags & PD_IOMMUV2_MASK)
24802493
goto out;
24812494

2482-
domain->glx = levels;
2483-
domain->flags |= PD_IOMMUV2_MASK;
2484-
2485-
amd_iommu_domain_update(domain);
2486-
2487-
ret = 0;
2495+
if (!pdom->gcr3_tbl)
2496+
ret = domain_enable_v2(pdom, pasids);
24882497

24892498
out:
2490-
spin_unlock_irqrestore(&domain->lock, flags);
2491-
2499+
spin_unlock_irqrestore(&pdom->lock, flags);
24922500
return ret;
24932501
}
24942502
EXPORT_SYMBOL(amd_iommu_domain_enable_v2);

0 commit comments

Comments
 (0)