Skip to content

Commit c208916

Browse files
rmurphy-armjoergroedel
authored andcommitted
iommu: Express DMA strictness via the domain type
Eliminate the iommu_get_dma_strict() indirection and pipe the information through the domain type from the beginning. Besides the flow simplification this also has several nice side-effects: - Automatically implies strict mode for untrusted devices by virtue of their IOMMU_DOMAIN_DMA override. - Ensures that we only end up using flush queues for drivers which are aware of them and can actually benefit. - Allows us to handle flush queue init failure by falling back to strict mode instead of leaving it to possibly blow up later. Reviewed-by: Lu Baolu <[email protected]> Signed-off-by: Robin Murphy <[email protected]> Link: https://lore.kernel.org/r/47083d69155577f1367877b1594921948c366eb3.1628682049.git.robin.murphy@arm.com Signed-off-by: Joerg Roedel <[email protected]>
1 parent 78ca078 commit c208916

File tree

3 files changed

+11
-14
lines changed

3 files changed

+11
-14
lines changed

drivers/iommu/dma-iommu.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -370,13 +370,15 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
370370

371371
init_iova_domain(iovad, 1UL << order, base_pfn);
372372

373-
if (!cookie->fq_domain && !dev_is_untrusted(dev) &&
374-
domain->ops->flush_iotlb_all && !iommu_get_dma_strict(domain)) {
373+
/* If the FQ fails we can simply fall back to strict mode */
374+
if (domain->type == IOMMU_DOMAIN_DMA_FQ && !cookie->fq_domain) {
375375
if (init_iova_flush_queue(iovad, iommu_dma_flush_iotlb_all,
376-
iommu_dma_entry_dtor))
376+
iommu_dma_entry_dtor)) {
377377
pr_warn("iova flush queue initialization failed\n");
378-
else
378+
domain->type = IOMMU_DOMAIN_DMA;
379+
} else {
379380
cookie->fq_domain = domain;
381+
}
380382
}
381383

382384
return iova_reserve_iommu_regions(dev, domain);

drivers/iommu/iommu.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ static int __init iommu_subsys_init(void)
136136
}
137137
}
138138

139+
if (!iommu_default_passthrough() && !iommu_dma_strict)
140+
iommu_def_domain_type = IOMMU_DOMAIN_DMA_FQ;
141+
139142
pr_info("Default domain type: %s %s\n",
140143
iommu_domain_type_str(iommu_def_domain_type),
141144
(iommu_cmd_line & IOMMU_CMD_LINE_DMA_API) ?
@@ -355,17 +358,10 @@ early_param("iommu.strict", iommu_dma_setup);
355358
void iommu_set_dma_strict(void)
356359
{
357360
iommu_dma_strict = true;
361+
if (iommu_def_domain_type == IOMMU_DOMAIN_DMA_FQ)
362+
iommu_def_domain_type = IOMMU_DOMAIN_DMA;
358363
}
359364

360-
bool iommu_get_dma_strict(struct iommu_domain *domain)
361-
{
362-
/* only allow lazy flushing for DMA domains */
363-
if (domain->type == IOMMU_DOMAIN_DMA)
364-
return iommu_dma_strict;
365-
return true;
366-
}
367-
EXPORT_SYMBOL_GPL(iommu_get_dma_strict);
368-
369365
static ssize_t iommu_group_attr_show(struct kobject *kobj,
370366
struct attribute *__attr, char *buf)
371367
{

include/linux/iommu.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,6 @@ int iommu_set_pgtable_quirks(struct iommu_domain *domain,
504504
unsigned long quirks);
505505

506506
void iommu_set_dma_strict(void);
507-
bool iommu_get_dma_strict(struct iommu_domain *domain);
508507

509508
extern int report_iommu_fault(struct iommu_domain *domain, struct device *dev,
510509
unsigned long iova, int flags);

0 commit comments

Comments
 (0)