aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Roedel <jroedel@suse.de>2015-05-28 12:41:34 -0400
committerJoerg Roedel <jroedel@suse.de>2015-06-09 02:55:24 -0400
commitbeed2821b4f42c268222c4c1f1795e53340acf64 (patch)
tree58b594e5b1790a8fc33b4d2418abbe811c1c21f4
parenta1015c2b99b94cf521603b41debf167114031456 (diff)
iommu: Create direct mappings in default domains
Use the information exported by the IOMMU drivers to create direct mapped regions in the default domains. Signed-off-by: Joerg Roedel <jroedel@suse.de>
-rw-r--r--drivers/iommu/iommu.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 6b8d6e7771e1..ffad1eaf450d 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -325,6 +325,52 @@ int iommu_group_set_name(struct iommu_group *group, const char *name)
325} 325}
326EXPORT_SYMBOL_GPL(iommu_group_set_name); 326EXPORT_SYMBOL_GPL(iommu_group_set_name);
327 327
328static int iommu_group_create_direct_mappings(struct iommu_group *group,
329 struct device *dev)
330{
331 struct iommu_domain *domain = group->default_domain;
332 struct iommu_dm_region *entry;
333 struct list_head mappings;
334 unsigned long pg_size;
335 int ret = 0;
336
337 if (!domain || domain->type != IOMMU_DOMAIN_DMA)
338 return 0;
339
340 BUG_ON(!domain->ops->pgsize_bitmap);
341
342 pg_size = 1UL << __ffs(domain->ops->pgsize_bitmap);
343 INIT_LIST_HEAD(&mappings);
344
345 iommu_get_dm_regions(dev, &mappings);
346
347 /* We need to consider overlapping regions for different devices */
348 list_for_each_entry(entry, &mappings, list) {
349 dma_addr_t start, end, addr;
350
351 start = ALIGN(entry->start, pg_size);
352 end = ALIGN(entry->start + entry->length, pg_size);
353
354 for (addr = start; addr < end; addr += pg_size) {
355 phys_addr_t phys_addr;
356
357 phys_addr = iommu_iova_to_phys(domain, addr);
358 if (phys_addr)
359 continue;
360
361 ret = iommu_map(domain, addr, addr, pg_size, entry->prot);
362 if (ret)
363 goto out;
364 }
365
366 }
367
368out:
369 iommu_put_dm_regions(dev, &mappings);
370
371 return ret;
372}
373
328/** 374/**
329 * iommu_group_add_device - add a device to an iommu group 375 * iommu_group_add_device - add a device to an iommu group
330 * @group: the group into which to add the device (reference should be held) 376 * @group: the group into which to add the device (reference should be held)
@@ -381,6 +427,8 @@ rename:
381 427
382 dev->iommu_group = group; 428 dev->iommu_group = group;
383 429
430 iommu_group_create_direct_mappings(group, dev);
431
384 mutex_lock(&group->mutex); 432 mutex_lock(&group->mutex);
385 list_add_tail(&device->list, &group->devices); 433 list_add_tail(&device->list, &group->devices);
386 if (group->domain) 434 if (group->domain)