diff options
author | Joerg Roedel <jroedel@suse.de> | 2015-07-21 14:53:04 +0200 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2015-08-12 16:23:33 +0200 |
commit | de24e55395698e29f2a0582ae1899fa0001f829a (patch) | |
tree | b597d0bb02dd5f2ce21280eb9dfd8605e86007fd /drivers/iommu | |
parent | iommu/vt-d: Calculate translation in domain_context_mapping_one (diff) | |
download | linux-de24e55395698e29f2a0582ae1899fa0001f829a.tar.xz linux-de24e55395698e29f2a0582ae1899fa0001f829a.zip |
iommu/vt-d: Simplify domain_context_mapping_one
Get rid of the special cases for VM domains vs. non-VM
domains and simplify the code further to just handle the
hardware passthrough vs. page-table case.
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu')
-rw-r--r-- | drivers/iommu/intel-iommu.c | 60 |
1 files changed, 26 insertions, 34 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index ca6ca3ddf349..5d4261ff67ad 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -1942,52 +1942,44 @@ static int domain_context_mapping_one(struct dmar_domain *domain, return 0; } - context_clear_entry(context); - - id = domain->id; pgd = domain->pgd; - if (domain_type_is_vm_or_si(domain)) { - if (domain_type_is_vm(domain)) { - 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; - } - } - - /* Skip top levels of page tables for - * iommu which has less agaw than default. - * Unnecessary for PT mode. - */ - if (translation != CONTEXT_TT_PASS_THROUGH) { - for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) { - pgd = phys_to_virt(dma_pte_addr(pgd)); - if (!dma_pte_present(pgd)) { - spin_unlock_irqrestore(&iommu->lock, flags); - return -ENOMEM; - } - } - } + 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); + /* + * Skip top levels of page tables for iommu which has less agaw + * than default. Unnecessary for PT mode. + */ if (translation != CONTEXT_TT_PASS_THROUGH) { + for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) { + pgd = phys_to_virt(dma_pte_addr(pgd)); + if (!dma_pte_present(pgd)) { + spin_unlock_irqrestore(&iommu->lock, flags); + return -ENOMEM; + } + } + info = iommu_support_dev_iotlb(domain, iommu, bus, devfn); translation = info ? CONTEXT_TT_DEV_IOTLB : CONTEXT_TT_MULTI_LEVEL; - } - /* - * In pass through mode, AW must be programmed to indicate the largest - * AGAW value supported by hardware. And ASR is ignored by hardware. - */ - if (unlikely(translation == CONTEXT_TT_PASS_THROUGH)) - context_set_address_width(context, iommu->msagaw); - else { + context_set_address_root(context, virt_to_phys(pgd)); context_set_address_width(context, iommu->agaw); + } else { + /* + * In pass through mode, AW must be programmed to + * indicate the largest AGAW value supported by + * hardware. And ASR is ignored by hardware. + */ + context_set_address_width(context, iommu->msagaw); } context_set_translation_type(context, translation); |