aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/admin-guide/kernel-parameters.txt12
-rw-r--r--drivers/iommu/iommu.c14
2 files changed, 26 insertions, 0 deletions
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 9871e649ffef..92ae12aeabf4 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1749,6 +1749,18 @@
1749 nobypass [PPC/POWERNV] 1749 nobypass [PPC/POWERNV]
1750 Disable IOMMU bypass, using IOMMU for PCI devices. 1750 Disable IOMMU bypass, using IOMMU for PCI devices.
1751 1751
1752 iommu.strict= [ARM64] Configure TLB invalidation behaviour
1753 Format: { "0" | "1" }
1754 0 - Lazy mode.
1755 Request that DMA unmap operations use deferred
1756 invalidation of hardware TLBs, for increased
1757 throughput at the cost of reduced device isolation.
1758 Will fall back to strict mode if not supported by
1759 the relevant IOMMU driver.
1760 1 - Strict mode (default).
1761 DMA unmap operations invalidate IOMMU hardware TLBs
1762 synchronously.
1763
1752 iommu.passthrough= 1764 iommu.passthrough=
1753 [ARM64] Configure DMA to bypass the IOMMU by default. 1765 [ARM64] Configure DMA to bypass the IOMMU by default.
1754 Format: { "0" | "1" } 1766 Format: { "0" | "1" }
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 8c15c5980299..2b6dad2aa9f1 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -41,6 +41,7 @@ static unsigned int iommu_def_domain_type = IOMMU_DOMAIN_IDENTITY;
41#else 41#else
42static unsigned int iommu_def_domain_type = IOMMU_DOMAIN_DMA; 42static unsigned int iommu_def_domain_type = IOMMU_DOMAIN_DMA;
43#endif 43#endif
44static bool iommu_dma_strict __read_mostly = true;
44 45
45struct iommu_callback_data { 46struct iommu_callback_data {
46 const struct iommu_ops *ops; 47 const struct iommu_ops *ops;
@@ -131,6 +132,12 @@ static int __init iommu_set_def_domain_type(char *str)
131} 132}
132early_param("iommu.passthrough", iommu_set_def_domain_type); 133early_param("iommu.passthrough", iommu_set_def_domain_type);
133 134
135static int __init iommu_dma_setup(char *str)
136{
137 return kstrtobool(str, &iommu_dma_strict);
138}
139early_param("iommu.strict", iommu_dma_setup);
140
134static ssize_t iommu_group_attr_show(struct kobject *kobj, 141static ssize_t iommu_group_attr_show(struct kobject *kobj,
135 struct attribute *__attr, char *buf) 142 struct attribute *__attr, char *buf)
136{ 143{
@@ -1072,6 +1079,13 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev)
1072 group->default_domain = dom; 1079 group->default_domain = dom;
1073 if (!group->domain) 1080 if (!group->domain)
1074 group->domain = dom; 1081 group->domain = dom;
1082
1083 if (dom && !iommu_dma_strict) {
1084 int attr = 1;
1085 iommu_domain_set_attr(dom,
1086 DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE,
1087 &attr);
1088 }
1075 } 1089 }
1076 1090
1077 ret = iommu_group_add_device(group, dev); 1091 ret = iommu_group_add_device(group, dev);