aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiang Liu <jiang.liu@linux.intel.com>2014-07-11 02:19:27 -0400
committerJoerg Roedel <jroedel@suse.de>2014-07-23 10:04:46 -0400
commitab8dfe251571e4a04d367e47e5be93976a77c610 (patch)
tree585c9aac66db081f7f4911b571e577f108150feb
parent18fd779a41eff52b597bd2d327194f98a83de4af (diff)
iommu/vt-d: Introduce helper functions to improve code readability
Introduce domain_type_is_vm() and domain_type_is_vm_or_si() to improve code readability. Also kill useless macro DOMAIN_FLAG_P2P_MULTIPLE_DEVICES. Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
-rw-r--r--drivers/iommu/intel-iommu.c59
1 files changed, 26 insertions, 33 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index d77009bdade5..52250b3e58d1 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -320,16 +320,13 @@ static inline int first_pte_in_page(struct dma_pte *pte)
320static struct dmar_domain *si_domain; 320static struct dmar_domain *si_domain;
321static int hw_pass_through = 1; 321static int hw_pass_through = 1;
322 322
323/* devices under the same p2p bridge are owned in one domain */
324#define DOMAIN_FLAG_P2P_MULTIPLE_DEVICES (1 << 0)
325
326/* domain represents a virtual machine, more than one devices 323/* domain represents a virtual machine, more than one devices
327 * across iommus may be owned in one domain, e.g. kvm guest. 324 * across iommus may be owned in one domain, e.g. kvm guest.
328 */ 325 */
329#define DOMAIN_FLAG_VIRTUAL_MACHINE (1 << 1) 326#define DOMAIN_FLAG_VIRTUAL_MACHINE (1 << 0)
330 327
331/* si_domain contains mulitple devices */ 328/* si_domain contains mulitple devices */
332#define DOMAIN_FLAG_STATIC_IDENTITY (1 << 2) 329#define DOMAIN_FLAG_STATIC_IDENTITY (1 << 1)
333 330
334/* define the limit of IOMMUs supported in each domain */ 331/* define the limit of IOMMUs supported in each domain */
335#ifdef CONFIG_X86 332#ifdef CONFIG_X86
@@ -539,6 +536,16 @@ void free_iova_mem(struct iova *iova)
539 kmem_cache_free(iommu_iova_cache, iova); 536 kmem_cache_free(iommu_iova_cache, iova);
540} 537}
541 538
539static inline int domain_type_is_vm(struct dmar_domain *domain)
540{
541 return domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE;
542}
543
544static inline int domain_type_is_vm_or_si(struct dmar_domain *domain)
545{
546 return domain->flags & (DOMAIN_FLAG_VIRTUAL_MACHINE |
547 DOMAIN_FLAG_STATIC_IDENTITY);
548}
542 549
543static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw) 550static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw)
544{ 551{
@@ -579,9 +586,7 @@ static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
579 int iommu_id; 586 int iommu_id;
580 587
581 /* si_domain and vm domain should not get here. */ 588 /* si_domain and vm domain should not get here. */
582 BUG_ON(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE); 589 BUG_ON(domain_type_is_vm_or_si(domain));
583 BUG_ON(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY);
584
585 iommu_id = find_first_bit(domain->iommu_bmp, g_num_of_iommus); 590 iommu_id = find_first_bit(domain->iommu_bmp, g_num_of_iommus);
586 if (iommu_id < 0 || iommu_id >= g_num_of_iommus) 591 if (iommu_id < 0 || iommu_id >= g_num_of_iommus)
587 return NULL; 592 return NULL;
@@ -1497,7 +1502,7 @@ static void free_dmar_iommu(struct intel_iommu *iommu)
1497 free_context_table(iommu); 1502 free_context_table(iommu);
1498} 1503}
1499 1504
1500static struct dmar_domain *alloc_domain(bool vm) 1505static struct dmar_domain *alloc_domain(int flags)
1501{ 1506{
1502 /* domain id for virtual machine, it won't be set in context */ 1507 /* domain id for virtual machine, it won't be set in context */
1503 static atomic_t vm_domid = ATOMIC_INIT(0); 1508 static atomic_t vm_domid = ATOMIC_INIT(0);
@@ -1507,16 +1512,13 @@ static struct dmar_domain *alloc_domain(bool vm)
1507 if (!domain) 1512 if (!domain)
1508 return NULL; 1513 return NULL;
1509 1514
1515 memset(domain, 0, sizeof(*domain));
1510 domain->nid = -1; 1516 domain->nid = -1;
1511 domain->iommu_count = 0; 1517 domain->flags = flags;
1512 memset(domain->iommu_bmp, 0, sizeof(domain->iommu_bmp));
1513 domain->flags = 0;
1514 spin_lock_init(&domain->iommu_lock); 1518 spin_lock_init(&domain->iommu_lock);
1515 INIT_LIST_HEAD(&domain->devices); 1519 INIT_LIST_HEAD(&domain->devices);
1516 if (vm) { 1520 if (flags & DOMAIN_FLAG_VIRTUAL_MACHINE)
1517 domain->id = atomic_inc_return(&vm_domid); 1521 domain->id = atomic_inc_return(&vm_domid);
1518 domain->flags = DOMAIN_FLAG_VIRTUAL_MACHINE;
1519 }
1520 1522
1521 return domain; 1523 return domain;
1522} 1524}
@@ -1704,7 +1706,7 @@ static void domain_exit(struct dmar_domain *domain)
1704 /* clear attached or cached domains */ 1706 /* clear attached or cached domains */
1705 rcu_read_lock(); 1707 rcu_read_lock();
1706 for_each_active_iommu(iommu, drhd) 1708 for_each_active_iommu(iommu, drhd)
1707 if (domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE || 1709 if (domain_type_is_vm(domain) ||
1708 test_bit(iommu->seq_id, domain->iommu_bmp)) 1710 test_bit(iommu->seq_id, domain->iommu_bmp))
1709 iommu_detach_domain(domain, iommu); 1711 iommu_detach_domain(domain, iommu);
1710 rcu_read_unlock(); 1712 rcu_read_unlock();
@@ -1746,8 +1748,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
1746 id = domain->id; 1748 id = domain->id;
1747 pgd = domain->pgd; 1749 pgd = domain->pgd;
1748 1750
1749 if (domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE || 1751 if (domain_type_is_vm_or_si(domain)) {
1750 domain->flags & DOMAIN_FLAG_STATIC_IDENTITY) {
1751 int found = 0; 1752 int found = 0;
1752 1753
1753 /* find an available domain id for this device in iommu */ 1754 /* find an available domain id for this device in iommu */
@@ -2094,7 +2095,7 @@ static void domain_remove_dev_info(struct dmar_domain *domain)
2094 iommu_disable_dev_iotlb(info); 2095 iommu_disable_dev_iotlb(info);
2095 iommu_detach_dev(info->iommu, info->bus, info->devfn); 2096 iommu_detach_dev(info->iommu, info->bus, info->devfn);
2096 2097
2097 if (domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) { 2098 if (domain_type_is_vm(domain)) {
2098 iommu_detach_dependent_devices(info->iommu, info->dev); 2099 iommu_detach_dependent_devices(info->iommu, info->dev);
2099 /* clear this iommu in iommu_bmp, update iommu count 2100 /* clear this iommu in iommu_bmp, update iommu count
2100 * and capabilities 2101 * and capabilities
@@ -2160,8 +2161,6 @@ static struct dmar_domain *dmar_insert_dev_info(struct intel_iommu *iommu,
2160 info->dev = dev; 2161 info->dev = dev;
2161 info->domain = domain; 2162 info->domain = domain;
2162 info->iommu = iommu; 2163 info->iommu = iommu;
2163 if (!dev)
2164 domain->flags |= DOMAIN_FLAG_P2P_MULTIPLE_DEVICES;
2165 2164
2166 spin_lock_irqsave(&device_domain_lock, flags); 2165 spin_lock_irqsave(&device_domain_lock, flags);
2167 if (dev) 2166 if (dev)
@@ -2233,7 +2232,7 @@ static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
2233 } 2232 }
2234 2233
2235 /* Allocate and initialize new domain for the device */ 2234 /* Allocate and initialize new domain for the device */
2236 domain = alloc_domain(false); 2235 domain = alloc_domain(0);
2237 if (!domain) 2236 if (!domain)
2238 return NULL; 2237 return NULL;
2239 2238
@@ -2408,12 +2407,10 @@ static int __init si_domain_init(int hw)
2408 struct intel_iommu *iommu; 2407 struct intel_iommu *iommu;
2409 int nid, ret = 0; 2408 int nid, ret = 0;
2410 2409
2411 si_domain = alloc_domain(false); 2410 si_domain = alloc_domain(DOMAIN_FLAG_STATIC_IDENTITY);
2412 if (!si_domain) 2411 if (!si_domain)
2413 return -EFAULT; 2412 return -EFAULT;
2414 2413
2415 si_domain->flags = DOMAIN_FLAG_STATIC_IDENTITY;
2416
2417 for_each_active_iommu(iommu, drhd) { 2414 for_each_active_iommu(iommu, drhd) {
2418 ret = iommu_attach_domain(si_domain, iommu); 2415 ret = iommu_attach_domain(si_domain, iommu);
2419 if (ret) { 2416 if (ret) {
@@ -3860,9 +3857,7 @@ static int device_notifier(struct notifier_block *nb,
3860 3857
3861 down_read(&dmar_global_lock); 3858 down_read(&dmar_global_lock);
3862 domain_remove_one_dev_info(domain, dev); 3859 domain_remove_one_dev_info(domain, dev);
3863 if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) && 3860 if (!domain_type_is_vm_or_si(domain) && list_empty(&domain->devices))
3864 !(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY) &&
3865 list_empty(&domain->devices))
3866 domain_exit(domain); 3861 domain_exit(domain);
3867 up_read(&dmar_global_lock); 3862 up_read(&dmar_global_lock);
3868 3863
@@ -4167,8 +4162,7 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain,
4167 domain_update_iommu_cap(domain); 4162 domain_update_iommu_cap(domain);
4168 spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags); 4163 spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags);
4169 4164
4170 if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) && 4165 if (!domain_type_is_vm_or_si(domain)) {
4171 !(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY)) {
4172 spin_lock_irqsave(&iommu->lock, tmp_flags); 4166 spin_lock_irqsave(&iommu->lock, tmp_flags);
4173 clear_bit(domain->id, iommu->domain_ids); 4167 clear_bit(domain->id, iommu->domain_ids);
4174 iommu->domains[domain->id] = NULL; 4168 iommu->domains[domain->id] = NULL;
@@ -4206,7 +4200,7 @@ static int intel_iommu_domain_init(struct iommu_domain *domain)
4206{ 4200{
4207 struct dmar_domain *dmar_domain; 4201 struct dmar_domain *dmar_domain;
4208 4202
4209 dmar_domain = alloc_domain(true); 4203 dmar_domain = alloc_domain(DOMAIN_FLAG_VIRTUAL_MACHINE);
4210 if (!dmar_domain) { 4204 if (!dmar_domain) {
4211 printk(KERN_ERR 4205 printk(KERN_ERR
4212 "intel_iommu_domain_init: dmar_domain == NULL\n"); 4206 "intel_iommu_domain_init: dmar_domain == NULL\n");
@@ -4250,8 +4244,7 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
4250 4244
4251 old_domain = find_domain(dev); 4245 old_domain = find_domain(dev);
4252 if (old_domain) { 4246 if (old_domain) {
4253 if (dmar_domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE || 4247 if (domain_type_is_vm_or_si(dmar_domain))
4254 dmar_domain->flags & DOMAIN_FLAG_STATIC_IDENTITY)
4255 domain_remove_one_dev_info(old_domain, dev); 4248 domain_remove_one_dev_info(old_domain, dev);
4256 else 4249 else
4257 domain_remove_dev_info(old_domain); 4250 domain_remove_dev_info(old_domain);