Skip to content

Commit fa954e6

Browse files
LuBaolujoergroedel
authored andcommitted
iommu/vt-d: Delegate the dma domain to upper layer
This allows the iommu generic layer to allocate a dma domain and attach it to a device through the iommu api's. With all types of domains being delegated to upper layer, we can remove an internal flag which was used to distinguish domains mananged internally or externally. Signed-off-by: James Sewart <[email protected]> Signed-off-by: Lu Baolu <[email protected]> Signed-off-by: Joerg Roedel <[email protected]>
1 parent 4de354e commit fa954e6

File tree

1 file changed

+19
-55
lines changed

1 file changed

+19
-55
lines changed

drivers/iommu/intel-iommu.c

Lines changed: 19 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -302,14 +302,8 @@ static inline void context_clear_entry(struct context_entry *context)
302302
static struct dmar_domain *si_domain;
303303
static int hw_pass_through = 1;
304304

305-
/*
306-
* Domain represents a virtual machine, more than one devices
307-
* across iommus may be owned in one domain, e.g. kvm guest.
308-
*/
309-
#define DOMAIN_FLAG_VIRTUAL_MACHINE (1 << 0)
310-
311305
/* si_domain contains mulitple devices */
312-
#define DOMAIN_FLAG_STATIC_IDENTITY (1 << 1)
306+
#define DOMAIN_FLAG_STATIC_IDENTITY BIT(0)
313307

314308
#define for_each_domain_iommu(idx, domain) \
315309
for (idx = 0; idx < g_num_of_iommus; idx++) \
@@ -540,22 +534,11 @@ static inline void free_devinfo_mem(void *vaddr)
540534
kmem_cache_free(iommu_devinfo_cache, vaddr);
541535
}
542536

543-
static inline int domain_type_is_vm(struct dmar_domain *domain)
544-
{
545-
return domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE;
546-
}
547-
548537
static inline int domain_type_is_si(struct dmar_domain *domain)
549538
{
550539
return domain->flags & DOMAIN_FLAG_STATIC_IDENTITY;
551540
}
552541

553-
static inline int domain_type_is_vm_or_si(struct dmar_domain *domain)
554-
{
555-
return domain->flags & (DOMAIN_FLAG_VIRTUAL_MACHINE |
556-
DOMAIN_FLAG_STATIC_IDENTITY);
557-
}
558-
559542
static inline int domain_pfn_supported(struct dmar_domain *domain,
560543
unsigned long pfn)
561544
{
@@ -603,7 +586,9 @@ struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
603586
int iommu_id;
604587

605588
/* si_domain and vm domain should not get here. */
606-
BUG_ON(domain_type_is_vm_or_si(domain));
589+
if (WARN_ON(domain->domain.type != IOMMU_DOMAIN_DMA))
590+
return NULL;
591+
607592
for_each_domain_iommu(iommu_id, domain)
608593
break;
609594

@@ -1651,7 +1636,6 @@ static void disable_dmar_iommu(struct intel_iommu *iommu)
16511636
if (!iommu->domains || !iommu->domain_ids)
16521637
return;
16531638

1654-
again:
16551639
spin_lock_irqsave(&device_domain_lock, flags);
16561640
list_for_each_entry_safe(info, tmp, &device_domain_list, global) {
16571641
struct dmar_domain *domain;
@@ -1665,18 +1649,6 @@ static void disable_dmar_iommu(struct intel_iommu *iommu)
16651649
domain = info->domain;
16661650

16671651
__dmar_remove_one_dev_info(info);
1668-
1669-
if (!domain_type_is_vm_or_si(domain)) {
1670-
/*
1671-
* The domain_exit() function can't be called under
1672-
* device_domain_lock, as it takes this lock itself.
1673-
* So release the lock here and re-run the loop
1674-
* afterwards.
1675-
*/
1676-
spin_unlock_irqrestore(&device_domain_lock, flags);
1677-
domain_exit(domain);
1678-
goto again;
1679-
}
16801652
}
16811653
spin_unlock_irqrestore(&device_domain_lock, flags);
16821654

@@ -2339,26 +2311,16 @@ static int domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
23392311
struct scatterlist *sg, unsigned long phys_pfn,
23402312
unsigned long nr_pages, int prot)
23412313
{
2342-
int ret;
2314+
int iommu_id, ret;
23432315
struct intel_iommu *iommu;
23442316

23452317
/* Do the real mapping first */
23462318
ret = __domain_mapping(domain, iov_pfn, sg, phys_pfn, nr_pages, prot);
23472319
if (ret)
23482320
return ret;
23492321

2350-
/* Notify about the new mapping */
2351-
if (domain_type_is_vm(domain)) {
2352-
/* VM typed domains can have more than one IOMMUs */
2353-
int iommu_id;
2354-
2355-
for_each_domain_iommu(iommu_id, domain) {
2356-
iommu = g_iommus[iommu_id];
2357-
__mapping_notify_one(iommu, domain, iov_pfn, nr_pages);
2358-
}
2359-
} else {
2360-
/* General domains only have one IOMMU */
2361-
iommu = domain_get_iommu(domain);
2322+
for_each_domain_iommu(iommu_id, domain) {
2323+
iommu = g_iommus[iommu_id];
23622324
__mapping_notify_one(iommu, domain, iov_pfn, nr_pages);
23632325
}
23642326

@@ -4599,9 +4561,6 @@ static int device_notifier(struct notifier_block *nb,
45994561
return 0;
46004562

46014563
dmar_remove_one_dev_info(dev);
4602-
if (!domain_type_is_vm_or_si(domain) &&
4603-
list_empty(&domain->devices))
4604-
domain_exit(domain);
46054564
} else if (action == BUS_NOTIFY_ADD_DEVICE) {
46064565
if (iommu_should_identity_map(dev, 1))
46074566
domain_add_dev_info(si_domain, dev);
@@ -5070,8 +5029,10 @@ static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
50705029
struct iommu_domain *domain;
50715030

50725031
switch (type) {
5032+
case IOMMU_DOMAIN_DMA:
5033+
/* fallthrough */
50735034
case IOMMU_DOMAIN_UNMANAGED:
5074-
dmar_domain = alloc_domain(DOMAIN_FLAG_VIRTUAL_MACHINE);
5035+
dmar_domain = alloc_domain(0);
50755036
if (!dmar_domain) {
50765037
pr_err("Can't allocate dmar_domain\n");
50775038
return NULL;
@@ -5081,6 +5042,14 @@ static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
50815042
domain_exit(dmar_domain);
50825043
return NULL;
50835044
}
5045+
5046+
if (type == IOMMU_DOMAIN_DMA &&
5047+
init_iova_flush_queue(&dmar_domain->iovad,
5048+
iommu_flush_iova, iova_entry_free)) {
5049+
pr_warn("iova flush queue initialization failed\n");
5050+
intel_iommu_strict = 1;
5051+
}
5052+
50845053
domain_update_iommu_cap(dmar_domain);
50855054

50865055
domain = &dmar_domain->domain;
@@ -5291,13 +5260,8 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
52915260
struct dmar_domain *old_domain;
52925261

52935262
old_domain = find_domain(dev);
5294-
if (old_domain) {
5263+
if (old_domain)
52955264
dmar_remove_one_dev_info(dev);
5296-
5297-
if (!domain_type_is_vm_or_si(old_domain) &&
5298-
list_empty(&old_domain->devices))
5299-
domain_exit(old_domain);
5300-
}
53015265
}
53025266

53035267
ret = prepare_domain_attach_device(domain, dev);

0 commit comments

Comments
 (0)