[PATCH 19/26] iommu/vt-d: Establish domain<->iommu link in dmar_insert_one_dev_info
From: Joerg Roedel
Date: Wed Aug 05 2015 - 11:21:50 EST
From: Joerg Roedel <jroedel@xxxxxxx>
This makes domain attachment more synchronous with domain
deattachment. The domain<->iommu link is released in
dmar_remove_one_dev_info.
Signed-off-by: Joerg Roedel <jroedel@xxxxxxx>
---
drivers/iommu/intel-iommu.c | 28 +++++++++++-----------------
1 file changed, 11 insertions(+), 17 deletions(-)
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 90c3fa5..27762d7 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -1916,14 +1916,16 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
struct intel_iommu *iommu,
u8 bus, u8 devfn)
{
+ u16 did = domain->iommu_did[iommu->seq_id];
int translation = CONTEXT_TT_MULTI_LEVEL;
struct device_domain_info *info = NULL;
struct context_entry *context;
unsigned long flags;
struct dma_pte *pgd;
- int id;
int agaw;
+ WARN_ON(did == 0);
+
translation = CONTEXT_TT_MULTI_LEVEL;
if (hw_pass_through && domain_type_is_si(domain))
translation = CONTEXT_TT_PASS_THROUGH;
@@ -1946,15 +1948,8 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
pgd = domain->pgd;
- id = __iommu_attach_domain(domain, iommu);
- if (id < 0) {
- spin_unlock_irqrestore(&iommu->lock, flags);
- pr_err("%s: No free domain ids\n", iommu->name);
- return -EFAULT;
- }
-
context_clear_entry(context);
- context_set_domain_id(context, id);
+ context_set_domain_id(context, did);
/*
* Skip top levels of page tables for iommu which has less agaw
@@ -2000,15 +1995,13 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
(((u16)bus) << 8) | devfn,
DMA_CCMD_MASK_NOBIT,
DMA_CCMD_DEVICE_INVL);
- iommu->flush.flush_iotlb(iommu, id, 0, 0, DMA_TLB_DSI_FLUSH);
+ iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
} else {
iommu_flush_write_buffer(iommu);
}
iommu_enable_dev_iotlb(info);
spin_unlock_irqrestore(&iommu->lock, flags);
- domain_attach_iommu(domain, iommu);
-
return 0;
}
@@ -2318,6 +2311,12 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
return found;
}
+ if (iommu_attach_domain(domain, iommu) < 0) {
+ spin_unlock_irqrestore(&device_domain_lock, flags);
+ return NULL;
+ }
+ domain_attach_iommu(domain, iommu);
+
list_add(&info->link, &domain->devices);
list_add(&info->global, &device_domain_list);
if (dev)
@@ -2381,11 +2380,6 @@ static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
domain = alloc_domain(0);
if (!domain)
return NULL;
- if (iommu_attach_domain(domain, iommu) < 0) {
- free_domain_mem(domain);
- return NULL;
- }
- domain_attach_iommu(domain, iommu);
if (domain_init(domain, iommu, gaw)) {
domain_exit(domain);
return NULL;
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/