Skip to content

Commit c0e8a6c

Browse files
committed
iommu/vt-d: Keep track of per-iommu domain ids
Instead of searching in the domain array for already allocated domain ids, keep track of them explicitly. Signed-off-by: Joerg Roedel <[email protected]>
1 parent 2238c08 commit c0e8a6c

File tree

1 file changed

+29
-25
lines changed

1 file changed

+29
-25
lines changed

drivers/iommu/intel-iommu.c

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,11 @@ struct dmar_domain {
378378
DECLARE_BITMAP(iommu_bmp, DMAR_UNITS_SUPPORTED);
379379
/* bitmap of iommus this domain uses*/
380380

381+
u16 iommu_did[DMAR_UNITS_SUPPORTED];
382+
/* Domain ids per IOMMU. Use u16 since
383+
* domain ids are 16 bit wide according
384+
* to VT-d spec, section 9.3 */
385+
381386
struct list_head devices; /* all devices' list */
382387
struct iova_domain iovad; /* iova's that belong to this domain */
383388

@@ -1543,11 +1548,13 @@ static int iommu_init_domains(struct intel_iommu *iommu)
15431548
}
15441549

15451550
/*
1546-
* if Caching mode is set, then invalid translations are tagged
1547-
* with domainid 0. Hence we need to pre-allocate it.
1551+
* If Caching mode is set, then invalid translations are tagged
1552+
* with domain-id 0, hence we need to pre-allocate it. We also
1553+
* use domain-id 0 as a marker for non-allocated domain-id, so
1554+
* make sure it is not used for a real domain.
15481555
*/
1549-
if (cap_caching_mode(iommu->cap))
1550-
set_bit(0, iommu->domain_ids);
1556+
set_bit(0, iommu->domain_ids);
1557+
15511558
return 0;
15521559
}
15531560

@@ -1560,9 +1567,10 @@ static void disable_dmar_iommu(struct intel_iommu *iommu)
15601567
for_each_set_bit(i, iommu->domain_ids, cap_ndoms(iommu->cap)) {
15611568
/*
15621569
* Domain id 0 is reserved for invalid translation
1563-
* if hardware supports caching mode.
1570+
* if hardware supports caching mode and used as
1571+
* a non-allocated marker.
15641572
*/
1565-
if (cap_caching_mode(iommu->cap) && i == 0)
1573+
if (i == 0)
15661574
continue;
15671575

15681576
domain = iommu->domains[i];
@@ -1624,6 +1632,7 @@ static int __iommu_attach_domain(struct dmar_domain *domain,
16241632
if (num < ndomains) {
16251633
set_bit(num, iommu->domain_ids);
16261634
iommu->domains[num] = domain;
1635+
domain->iommu_did[iommu->seq_id] = num;
16271636
} else {
16281637
num = -ENOSPC;
16291638
}
@@ -1650,12 +1659,10 @@ static int iommu_attach_vm_domain(struct dmar_domain *domain,
16501659
struct intel_iommu *iommu)
16511660
{
16521661
int num;
1653-
unsigned long ndomains;
16541662

1655-
ndomains = cap_ndoms(iommu->cap);
1656-
for_each_set_bit(num, iommu->domain_ids, ndomains)
1657-
if (iommu->domains[num] == domain)
1658-
return num;
1663+
num = domain->iommu_did[iommu->seq_id];
1664+
if (num)
1665+
return num;
16591666

16601667
return __iommu_attach_domain(domain, iommu);
16611668
}
@@ -1664,22 +1671,18 @@ static void iommu_detach_domain(struct dmar_domain *domain,
16641671
struct intel_iommu *iommu)
16651672
{
16661673
unsigned long flags;
1667-
int num, ndomains;
1674+
int num;
16681675

16691676
spin_lock_irqsave(&iommu->lock, flags);
1670-
if (domain_type_is_vm_or_si(domain)) {
1671-
ndomains = cap_ndoms(iommu->cap);
1672-
for_each_set_bit(num, iommu->domain_ids, ndomains) {
1673-
if (iommu->domains[num] == domain) {
1674-
clear_bit(num, iommu->domain_ids);
1675-
iommu->domains[num] = NULL;
1676-
break;
1677-
}
1678-
}
1679-
} else {
1680-
clear_bit(domain->id, iommu->domain_ids);
1681-
iommu->domains[domain->id] = NULL;
1682-
}
1677+
1678+
num = domain->iommu_did[iommu->seq_id];
1679+
1680+
if (num == 0)
1681+
return;
1682+
1683+
clear_bit(num, iommu->domain_ids);
1684+
iommu->domains[num] = NULL;
1685+
16831686
spin_unlock_irqrestore(&iommu->lock, flags);
16841687
}
16851688

@@ -1708,6 +1711,7 @@ static int domain_detach_iommu(struct dmar_domain *domain,
17081711
if (test_and_clear_bit(iommu->seq_id, domain->iommu_bmp)) {
17091712
count = --domain->iommu_count;
17101713
domain_update_iommu_cap(domain);
1714+
domain->iommu_did[iommu->seq_id] = 0;
17111715
}
17121716
spin_unlock_irqrestore(&domain->iommu_lock, flags);
17131717

0 commit comments

Comments
 (0)