Commit ab8dfe25 authored by Jiang Liu's avatar Jiang Liu Committed by Joerg Roedel

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: default avatarJiang Liu <jiang.liu@linux.intel.com>
Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent 18fd779a
...@@ -320,16 +320,13 @@ static inline int first_pte_in_page(struct dma_pte *pte) ...@@ -320,16 +320,13 @@ static inline int first_pte_in_page(struct dma_pte *pte)
static struct dmar_domain *si_domain; static struct dmar_domain *si_domain;
static int hw_pass_through = 1; static int hw_pass_through = 1;
/* devices under the same p2p bridge are owned in one domain */
#define DOMAIN_FLAG_P2P_MULTIPLE_DEVICES (1 << 0)
/* domain represents a virtual machine, more than one devices /* domain represents a virtual machine, more than one devices
* across iommus may be owned in one domain, e.g. kvm guest. * across iommus may be owned in one domain, e.g. kvm guest.
*/ */
#define DOMAIN_FLAG_VIRTUAL_MACHINE (1 << 1) #define DOMAIN_FLAG_VIRTUAL_MACHINE (1 << 0)
/* si_domain contains mulitple devices */ /* si_domain contains mulitple devices */
#define DOMAIN_FLAG_STATIC_IDENTITY (1 << 2) #define DOMAIN_FLAG_STATIC_IDENTITY (1 << 1)
/* define the limit of IOMMUs supported in each domain */ /* define the limit of IOMMUs supported in each domain */
#ifdef CONFIG_X86 #ifdef CONFIG_X86
...@@ -539,6 +536,16 @@ void free_iova_mem(struct iova *iova) ...@@ -539,6 +536,16 @@ void free_iova_mem(struct iova *iova)
kmem_cache_free(iommu_iova_cache, iova); kmem_cache_free(iommu_iova_cache, iova);
} }
static inline int domain_type_is_vm(struct dmar_domain *domain)
{
return domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE;
}
static inline int domain_type_is_vm_or_si(struct dmar_domain *domain)
{
return domain->flags & (DOMAIN_FLAG_VIRTUAL_MACHINE |
DOMAIN_FLAG_STATIC_IDENTITY);
}
static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw) static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw)
{ {
...@@ -579,9 +586,7 @@ static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain) ...@@ -579,9 +586,7 @@ static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
int iommu_id; int iommu_id;
/* si_domain and vm domain should not get here. */ /* si_domain and vm domain should not get here. */
BUG_ON(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE); BUG_ON(domain_type_is_vm_or_si(domain));
BUG_ON(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY);
iommu_id = find_first_bit(domain->iommu_bmp, g_num_of_iommus); iommu_id = find_first_bit(domain->iommu_bmp, g_num_of_iommus);
if (iommu_id < 0 || iommu_id >= g_num_of_iommus) if (iommu_id < 0 || iommu_id >= g_num_of_iommus)
return NULL; return NULL;
...@@ -1497,7 +1502,7 @@ static void free_dmar_iommu(struct intel_iommu *iommu) ...@@ -1497,7 +1502,7 @@ static void free_dmar_iommu(struct intel_iommu *iommu)
free_context_table(iommu); free_context_table(iommu);
} }
static struct dmar_domain *alloc_domain(bool vm) static struct dmar_domain *alloc_domain(int flags)
{ {
/* domain id for virtual machine, it won't be set in context */ /* domain id for virtual machine, it won't be set in context */
static atomic_t vm_domid = ATOMIC_INIT(0); static atomic_t vm_domid = ATOMIC_INIT(0);
...@@ -1507,16 +1512,13 @@ static struct dmar_domain *alloc_domain(bool vm) ...@@ -1507,16 +1512,13 @@ static struct dmar_domain *alloc_domain(bool vm)
if (!domain) if (!domain)
return NULL; return NULL;
memset(domain, 0, sizeof(*domain));
domain->nid = -1; domain->nid = -1;
domain->iommu_count = 0; domain->flags = flags;
memset(domain->iommu_bmp, 0, sizeof(domain->iommu_bmp));
domain->flags = 0;
spin_lock_init(&domain->iommu_lock); spin_lock_init(&domain->iommu_lock);
INIT_LIST_HEAD(&domain->devices); INIT_LIST_HEAD(&domain->devices);
if (vm) { if (flags & DOMAIN_FLAG_VIRTUAL_MACHINE)
domain->id = atomic_inc_return(&vm_domid); domain->id = atomic_inc_return(&vm_domid);
domain->flags = DOMAIN_FLAG_VIRTUAL_MACHINE;
}
return domain; return domain;
} }
...@@ -1704,7 +1706,7 @@ static void domain_exit(struct dmar_domain *domain) ...@@ -1704,7 +1706,7 @@ static void domain_exit(struct dmar_domain *domain)
/* clear attached or cached domains */ /* clear attached or cached domains */
rcu_read_lock(); rcu_read_lock();
for_each_active_iommu(iommu, drhd) for_each_active_iommu(iommu, drhd)
if (domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE || if (domain_type_is_vm(domain) ||
test_bit(iommu->seq_id, domain->iommu_bmp)) test_bit(iommu->seq_id, domain->iommu_bmp))
iommu_detach_domain(domain, iommu); iommu_detach_domain(domain, iommu);
rcu_read_unlock(); rcu_read_unlock();
...@@ -1746,8 +1748,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain, ...@@ -1746,8 +1748,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
id = domain->id; id = domain->id;
pgd = domain->pgd; pgd = domain->pgd;
if (domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE || if (domain_type_is_vm_or_si(domain)) {
domain->flags & DOMAIN_FLAG_STATIC_IDENTITY) {
int found = 0; int found = 0;
/* find an available domain id for this device in iommu */ /* 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,7 +2095,7 @@ static void domain_remove_dev_info(struct dmar_domain *domain)
iommu_disable_dev_iotlb(info); iommu_disable_dev_iotlb(info);
iommu_detach_dev(info->iommu, info->bus, info->devfn); iommu_detach_dev(info->iommu, info->bus, info->devfn);
if (domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) { if (domain_type_is_vm(domain)) {
iommu_detach_dependent_devices(info->iommu, info->dev); iommu_detach_dependent_devices(info->iommu, info->dev);
/* clear this iommu in iommu_bmp, update iommu count /* clear this iommu in iommu_bmp, update iommu count
* and capabilities * and capabilities
...@@ -2160,8 +2161,6 @@ static struct dmar_domain *dmar_insert_dev_info(struct intel_iommu *iommu, ...@@ -2160,8 +2161,6 @@ static struct dmar_domain *dmar_insert_dev_info(struct intel_iommu *iommu,
info->dev = dev; info->dev = dev;
info->domain = domain; info->domain = domain;
info->iommu = iommu; info->iommu = iommu;
if (!dev)
domain->flags |= DOMAIN_FLAG_P2P_MULTIPLE_DEVICES;
spin_lock_irqsave(&device_domain_lock, flags); spin_lock_irqsave(&device_domain_lock, flags);
if (dev) if (dev)
...@@ -2233,7 +2232,7 @@ static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw) ...@@ -2233,7 +2232,7 @@ static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
} }
/* Allocate and initialize new domain for the device */ /* Allocate and initialize new domain for the device */
domain = alloc_domain(false); domain = alloc_domain(0);
if (!domain) if (!domain)
return NULL; return NULL;
...@@ -2408,12 +2407,10 @@ static int __init si_domain_init(int hw) ...@@ -2408,12 +2407,10 @@ static int __init si_domain_init(int hw)
struct intel_iommu *iommu; struct intel_iommu *iommu;
int nid, ret = 0; int nid, ret = 0;
si_domain = alloc_domain(false); si_domain = alloc_domain(DOMAIN_FLAG_STATIC_IDENTITY);
if (!si_domain) if (!si_domain)
return -EFAULT; return -EFAULT;
si_domain->flags = DOMAIN_FLAG_STATIC_IDENTITY;
for_each_active_iommu(iommu, drhd) { for_each_active_iommu(iommu, drhd) {
ret = iommu_attach_domain(si_domain, iommu); ret = iommu_attach_domain(si_domain, iommu);
if (ret) { if (ret) {
...@@ -3860,9 +3857,7 @@ static int device_notifier(struct notifier_block *nb, ...@@ -3860,9 +3857,7 @@ static int device_notifier(struct notifier_block *nb,
down_read(&dmar_global_lock); down_read(&dmar_global_lock);
domain_remove_one_dev_info(domain, dev); domain_remove_one_dev_info(domain, dev);
if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) && if (!domain_type_is_vm_or_si(domain) && list_empty(&domain->devices))
!(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY) &&
list_empty(&domain->devices))
domain_exit(domain); domain_exit(domain);
up_read(&dmar_global_lock); up_read(&dmar_global_lock);
...@@ -4167,8 +4162,7 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain, ...@@ -4167,8 +4162,7 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain,
domain_update_iommu_cap(domain); domain_update_iommu_cap(domain);
spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags); spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags);
if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) && if (!domain_type_is_vm_or_si(domain)) {
!(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY)) {
spin_lock_irqsave(&iommu->lock, tmp_flags); spin_lock_irqsave(&iommu->lock, tmp_flags);
clear_bit(domain->id, iommu->domain_ids); clear_bit(domain->id, iommu->domain_ids);
iommu->domains[domain->id] = NULL; iommu->domains[domain->id] = NULL;
...@@ -4206,7 +4200,7 @@ static int intel_iommu_domain_init(struct iommu_domain *domain) ...@@ -4206,7 +4200,7 @@ static int intel_iommu_domain_init(struct iommu_domain *domain)
{ {
struct dmar_domain *dmar_domain; struct dmar_domain *dmar_domain;
dmar_domain = alloc_domain(true); dmar_domain = alloc_domain(DOMAIN_FLAG_VIRTUAL_MACHINE);
if (!dmar_domain) { if (!dmar_domain) {
printk(KERN_ERR printk(KERN_ERR
"intel_iommu_domain_init: dmar_domain == NULL\n"); "intel_iommu_domain_init: dmar_domain == NULL\n");
...@@ -4250,8 +4244,7 @@ static int intel_iommu_attach_device(struct iommu_domain *domain, ...@@ -4250,8 +4244,7 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
old_domain = find_domain(dev); old_domain = find_domain(dev);
if (old_domain) { if (old_domain) {
if (dmar_domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE || if (domain_type_is_vm_or_si(dmar_domain))
dmar_domain->flags & DOMAIN_FLAG_STATIC_IDENTITY)
domain_remove_one_dev_info(old_domain, dev); domain_remove_one_dev_info(old_domain, dev);
else else
domain_remove_dev_info(old_domain); domain_remove_dev_info(old_domain);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment