diff options
author | Jiang Liu <jiang.liu@linux.intel.com> | 2014-07-11 02:19:27 -0400 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2014-07-23 10:04:46 -0400 |
commit | ab8dfe251571e4a04d367e47e5be93976a77c610 (patch) | |
tree | 585c9aac66db081f7f4911b571e577f108150feb | |
parent | 18fd779a41eff52b597bd2d327194f98a83de4af (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.c | 59 |
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) | |||
320 | static struct dmar_domain *si_domain; | 320 | static struct dmar_domain *si_domain; |
321 | static int hw_pass_through = 1; | 321 | static 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 | ||
539 | static inline int domain_type_is_vm(struct dmar_domain *domain) | ||
540 | { | ||
541 | return domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE; | ||
542 | } | ||
543 | |||
544 | static 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 | ||
543 | static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw) | 550 | static 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 | ||
1500 | static struct dmar_domain *alloc_domain(bool vm) | 1505 | static 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); |