linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 0/6] add generic boot option for IOMMU dma mode
@ 2019-04-09 12:53 Zhen Lei
  2019-04-09 12:53 ` [PATCH v5 1/6] iommu: add generic boot option iommu.dma_mode Zhen Lei
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: Zhen Lei @ 2019-04-09 12:53 UTC (permalink / raw)
  To: Jean-Philippe Brucker, John Garry, Robin Murphy, Will Deacon,
	Joerg Roedel, Jonathan Corbet, linux-doc, Sebastian Ott,
	Gerald Schaefer, Martin Schwidefsky, Heiko Carstens,
	Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Tony Luck, Fenghua Yu, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, David Woodhouse, iommu,
	linux-kernel, linux-s390, linuxppc-dev, x86, linux-ia64
  Cc: Zhen Lei, Hanjun Guo

v4 --> v5:
As Hanjun and Thomas Gleixner's suggestion:
1. Keep the old ARCH specific boot options no change.
2. Keep build option CONFIG_IOMMU_DEFAULT_PASSTHROUGH no change.

v4:
As Robin Murphy's suggestion:
"It's also not necessarily obvious to the user how this interacts with
IOMMU_DEFAULT_PASSTHROUGH, so if we really do go down this route, maybe it
would be better to refactor the whole lot into a single selection of something
like IOMMU_DEFAULT_MODE anyway."

In this version, I tried to normalize the IOMMU dma mode boot options for all
ARCHs. When IOMMU is enabled, there are 3 dma modes: paasthrough(bypass),
lazy(mapping but defer the IOTLB invalidation), strict. But currently each
ARCHs defined their private boot options, different with each other. For
example, to enable/disable "passthrough", ARM64 use iommu.passthrough=1/0,
X86 use iommu=pt/nopt, PPC/POWERNV use iommu=nobypass.

Zhen Lei (6):
  iommu: add generic boot option iommu.dma_mode
  iommu: add build options corresponding to iommu.dma_mode
  iommu: add iommu_default_dma_mode_get/set() helper
  s390/pci: add support for generic boot option iommu.dma_mode
  powernv/iommu: add support for generic boot option iommu.dma_mode
  x86/iommu: add support for generic boot option iommu.dma_mode

 Documentation/admin-guide/kernel-parameters.txt | 19 +++++++
 arch/ia64/include/asm/iommu.h                   |  2 -
 arch/ia64/kernel/pci-dma.c                      |  2 -
 arch/powerpc/platforms/powernv/pci-ioda.c       |  5 +-
 arch/s390/pci/pci_dma.c                         | 14 ++---
 arch/x86/include/asm/iommu.h                    |  1 -
 arch/x86/kernel/pci-dma.c                       | 35 ++++++------
 drivers/iommu/Kconfig                           | 45 ++++++++++++---
 drivers/iommu/amd_iommu.c                       | 10 ++--
 drivers/iommu/amd_iommu_init.c                  |  4 +-
 drivers/iommu/amd_iommu_types.h                 |  6 --
 drivers/iommu/intel-iommu.c                     |  9 ++-
 drivers/iommu/iommu.c                           | 73 ++++++++++++++++++++-----
 include/linux/iommu.h                           | 23 ++++++++
 14 files changed, 176 insertions(+), 72 deletions(-)

-- 
1.8.3



^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v5 1/6] iommu: add generic boot option iommu.dma_mode
  2019-04-09 12:53 [PATCH v5 0/6] add generic boot option for IOMMU dma mode Zhen Lei
@ 2019-04-09 12:53 ` Zhen Lei
  2019-04-12 10:26   ` John Garry
  2019-04-12 11:16   ` Joerg Roedel
  2019-04-09 12:53 ` [PATCH v5 2/6] iommu: add build options corresponding to iommu.dma_mode Zhen Lei
                   ` (4 subsequent siblings)
  5 siblings, 2 replies; 14+ messages in thread
From: Zhen Lei @ 2019-04-09 12:53 UTC (permalink / raw)
  To: Jean-Philippe Brucker, John Garry, Robin Murphy, Will Deacon,
	Joerg Roedel, Jonathan Corbet, linux-doc, Sebastian Ott,
	Gerald Schaefer, Martin Schwidefsky, Heiko Carstens,
	Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Tony Luck, Fenghua Yu, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, David Woodhouse, iommu,
	linux-kernel, linux-s390, linuxppc-dev, x86, linux-ia64
  Cc: Zhen Lei, Hanjun Guo

Currently the IOMMU dma contains 3 modes: passthrough, lazy, strict. The
passthrough mode bypass the IOMMU, the lazy mode defer the invalidation
of hardware TLBs, and the strict mode invalidate IOMMU hardware TLBs
synchronously. The three modes are mutually exclusive. But the current
boot options are confused, such as: iommu.passthrough and iommu.strict,
because they are no good to be coexist. So add iommu.dma_mode.

Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
---
 Documentation/admin-guide/kernel-parameters.txt | 19 ++++++++
 drivers/iommu/iommu.c                           | 59 ++++++++++++++++++++-----
 include/linux/iommu.h                           |  5 +++
 3 files changed, 71 insertions(+), 12 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 2b8ee90bb64470d..f7766f8ac8b9084 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1811,6 +1811,25 @@
 			1 - Bypass the IOMMU for DMA.
 			unset - Use value of CONFIG_IOMMU_DEFAULT_PASSTHROUGH.
 
+	iommu.dma_mode= Configure default dma mode. if unset, use the value
+			of CONFIG_IOMMU_DEFAULT_PASSTHROUGH to determine
+			passthrough or not.
+			Note: For historical reasons, ARM64/S390/PPC/X86 have
+			their specific options. Currently, only ARM64 support
+			this boot option, and hope other ARCHs to use this as
+			generic boot option.
+		passthrough
+			Configure DMA to bypass the IOMMU by default.
+		lazy
+			Request that DMA unmap operations use deferred
+			invalidation of hardware TLBs, for increased
+			throughput at the cost of reduced device isolation.
+			Will fall back to strict mode if not supported by
+			the relevant IOMMU driver.
+		strict
+			DMA unmap operations invalidate IOMMU hardware TLBs
+			synchronously.
+
 	io7=		[HW] IO7 for Marvel based alpha systems
 			See comment before marvel_specify_io7 in
 			arch/alpha/kernel/core_marvel.c.
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 109de67d5d727c2..df1ce8e22385b48 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -38,12 +38,13 @@
 
 static struct kset *iommu_group_kset;
 static DEFINE_IDA(iommu_group_ida);
+
 #ifdef CONFIG_IOMMU_DEFAULT_PASSTHROUGH
-static unsigned int iommu_def_domain_type = IOMMU_DOMAIN_IDENTITY;
+#define IOMMU_DEFAULT_DMA_MODE		IOMMU_DMA_MODE_PASSTHROUGH
 #else
-static unsigned int iommu_def_domain_type = IOMMU_DOMAIN_DMA;
+#define IOMMU_DEFAULT_DMA_MODE		IOMMU_DMA_MODE_STRICT
 #endif
-static bool iommu_dma_strict __read_mostly = true;
+static int iommu_default_dma_mode __read_mostly = IOMMU_DEFAULT_DMA_MODE;
 
 struct iommu_callback_data {
 	const struct iommu_ops *ops;
@@ -147,20 +148,51 @@ static int __init iommu_set_def_domain_type(char *str)
 	int ret;
 
 	ret = kstrtobool(str, &pt);
-	if (ret)
-		return ret;
+	if (!ret && pt)
+		iommu_default_dma_mode = IOMMU_DMA_MODE_PASSTHROUGH;
 
-	iommu_def_domain_type = pt ? IOMMU_DOMAIN_IDENTITY : IOMMU_DOMAIN_DMA;
-	return 0;
+	return ret;
 }
 early_param("iommu.passthrough", iommu_set_def_domain_type);
 
 static int __init iommu_dma_setup(char *str)
 {
-	return kstrtobool(str, &iommu_dma_strict);
+	bool strict;
+	int ret;
+
+	ret = kstrtobool(str, &strict);
+	if (!ret)
+		iommu_default_dma_mode = strict ?
+				IOMMU_DMA_MODE_STRICT : IOMMU_DMA_MODE_LAZY;
+
+	return ret;
 }
 early_param("iommu.strict", iommu_dma_setup);
 
+static int __init iommu_dma_mode_setup(char *str)
+{
+	if (!str)
+		goto fail;
+
+	if (!strncmp(str, "passthrough", 11))
+		iommu_default_dma_mode = IOMMU_DMA_MODE_PASSTHROUGH;
+	else if (!strncmp(str, "lazy", 4))
+		iommu_default_dma_mode = IOMMU_DMA_MODE_LAZY;
+	else if (!strncmp(str, "strict", 6))
+		iommu_default_dma_mode = IOMMU_DMA_MODE_STRICT;
+	else
+		goto fail;
+
+	pr_info("Force dma mode to be %d\n", iommu_default_dma_mode);
+
+	return 0;
+
+fail:
+	pr_debug("Boot option iommu.dma_mode is incorrect, ignored\n");
+	return -EINVAL;
+}
+early_param("iommu.dma_mode", iommu_dma_mode_setup);
+
 static ssize_t iommu_group_attr_show(struct kobject *kobj,
 				     struct attribute *__attr, char *buf)
 {
@@ -1102,14 +1134,17 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev)
 	 */
 	if (!group->default_domain) {
 		struct iommu_domain *dom;
+		int def_domain_type =
+			(iommu_default_dma_mode == IOMMU_DMA_MODE_PASSTHROUGH)
+			? IOMMU_DOMAIN_IDENTITY : IOMMU_DOMAIN_DMA;
 
-		dom = __iommu_domain_alloc(dev->bus, iommu_def_domain_type);
-		if (!dom && iommu_def_domain_type != IOMMU_DOMAIN_DMA) {
+		dom = __iommu_domain_alloc(dev->bus, def_domain_type);
+		if (!dom && def_domain_type != IOMMU_DOMAIN_DMA) {
 			dom = __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_DMA);
 			if (dom) {
 				dev_warn(dev,
 					 "failed to allocate default IOMMU domain of type %u; falling back to IOMMU_DOMAIN_DMA",
-					 iommu_def_domain_type);
+					 def_domain_type);
 			}
 		}
 
@@ -1117,7 +1152,7 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev)
 		if (!group->domain)
 			group->domain = dom;
 
-		if (dom && !iommu_dma_strict) {
+		if (dom && (iommu_default_dma_mode == IOMMU_DMA_MODE_LAZY)) {
 			int attr = 1;
 			iommu_domain_set_attr(dom,
 					      DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE,
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index ffbbc7e39ceeba3..c3f4e3416176496 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -42,6 +42,11 @@
  */
 #define IOMMU_PRIV	(1 << 5)
 
+
+#define IOMMU_DMA_MODE_STRICT		0x0
+#define IOMMU_DMA_MODE_LAZY		0x1
+#define IOMMU_DMA_MODE_PASSTHROUGH	0x2
+
 struct iommu_ops;
 struct iommu_group;
 struct bus_type;
-- 
1.8.3



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v5 2/6] iommu: add build options corresponding to iommu.dma_mode
  2019-04-09 12:53 [PATCH v5 0/6] add generic boot option for IOMMU dma mode Zhen Lei
  2019-04-09 12:53 ` [PATCH v5 1/6] iommu: add generic boot option iommu.dma_mode Zhen Lei
@ 2019-04-09 12:53 ` Zhen Lei
  2019-04-09 12:53 ` [PATCH v5 3/6] iommu: add iommu_default_dma_mode_get/set() helper Zhen Lei
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Zhen Lei @ 2019-04-09 12:53 UTC (permalink / raw)
  To: Jean-Philippe Brucker, John Garry, Robin Murphy, Will Deacon,
	Joerg Roedel, Jonathan Corbet, linux-doc, Sebastian Ott,
	Gerald Schaefer, Martin Schwidefsky, Heiko Carstens,
	Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Tony Luck, Fenghua Yu, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, David Woodhouse, iommu,
	linux-kernel, linux-s390, linuxppc-dev, x86, linux-ia64
  Cc: Zhen Lei, Hanjun Guo

First, add build option IOMMU_DEFAULT_{LAZY|STRICT}, so that we have the
opportunity to set {lazy|strict} mode as default at build time. Then put
the three config options in an choice, make people can only choose one of
the three at a time, the same to the boot options iommu.dma_mode.

Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
---
 Documentation/admin-guide/kernel-parameters.txt |  6 ++--
 drivers/iommu/Kconfig                           | 43 +++++++++++++++++++++----
 drivers/iommu/iommu.c                           |  4 ++-
 3 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index f7766f8ac8b9084..92d1b3151d003c2 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1811,9 +1811,9 @@
 			1 - Bypass the IOMMU for DMA.
 			unset - Use value of CONFIG_IOMMU_DEFAULT_PASSTHROUGH.
 
-	iommu.dma_mode= Configure default dma mode. if unset, use the value
-			of CONFIG_IOMMU_DEFAULT_PASSTHROUGH to determine
-			passthrough or not.
+	iommu.dma_mode= Configure default dma mode. if unset, use the build
+			options(such as CONFIG_IOMMU_DEFAULT_PASSTHROUGH) to
+			choose which mode to be used.
 			Note: For historical reasons, ARM64/S390/PPC/X86 have
 			their specific options. Currently, only ARM64 support
 			this boot option, and hope other ARCHs to use this as
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 6f07f3b21816c64..1986f9767da488b 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -74,17 +74,46 @@ config IOMMU_DEBUGFS
 	  debug/iommu directory, and then populate a subdirectory with
 	  entries as required.
 
-config IOMMU_DEFAULT_PASSTHROUGH
-	bool "IOMMU passthrough by default"
+choice
+	prompt "IOMMU dma mode"
 	depends on IOMMU_API
-        help
-	  Enable passthrough by default, removing the need to pass in
-	  iommu.passthrough=on or iommu=pt through command line. If this
-	  is enabled, you can still disable with iommu.passthrough=off
-	  or iommu=nopt depending on the architecture.
+	default IOMMU_DEFAULT_STRICT
+	help
+	  This option allows IOMMU dma mode to be chose at build time, to
+	  override the default dma mode of each ARCHs, removing the need to
+	  pass in kernel parameters through command line. You can still use the
+	  generic boot option iommu.dma_mode or ARCHs specific boot options to
+	  override this option again.
+
+config IOMMU_DEFAULT_PASSTHROUGH
+	bool "passthrough"
+	help
+	  In this mode, the dma access through IOMMU without any addresses
+	  transformation. That means, the wrong or illegal dma access can not
+	  be caught, no error information will be reported.
 
 	  If unsure, say N here.
 
+config IOMMU_DEFAULT_LAZY
+	bool "lazy"
+	help
+	  Support lazy mode, where for every IOMMU DMA unmap operation, the
+	  flush operation of IOTLB and the free operation of IOVA are deferred.
+	  They are only guaranteed to be done before the related IOVA will be
+	  reused.
+
+config IOMMU_DEFAULT_STRICT
+	bool "strict"
+	help
+	  For every IOMMU DMA unmap operation, the flush operation of IOTLB and
+	  the free operation of IOVA are guaranteed to be done in the unmap
+	  function.
+
+	  This mode is safer than the two above, but it maybe slow in some high
+	  performace scenarios.
+
+endchoice
+
 config OF_IOMMU
        def_bool y
        depends on OF && IOMMU_API
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index df1ce8e22385b48..f4171bf4b46eaeb 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -39,8 +39,10 @@
 static struct kset *iommu_group_kset;
 static DEFINE_IDA(iommu_group_ida);
 
-#ifdef CONFIG_IOMMU_DEFAULT_PASSTHROUGH
+#if defined(CONFIG_IOMMU_DEFAULT_PASSTHROUGH)
 #define IOMMU_DEFAULT_DMA_MODE		IOMMU_DMA_MODE_PASSTHROUGH
+#elif defined(CONFIG_IOMMU_DEFAULT_LAZY)
+#define IOMMU_DEFAULT_DMA_MODE		IOMMU_DMA_MODE_LAZY
 #else
 #define IOMMU_DEFAULT_DMA_MODE		IOMMU_DMA_MODE_STRICT
 #endif
-- 
1.8.3



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v5 3/6] iommu: add iommu_default_dma_mode_get/set() helper
  2019-04-09 12:53 [PATCH v5 0/6] add generic boot option for IOMMU dma mode Zhen Lei
  2019-04-09 12:53 ` [PATCH v5 1/6] iommu: add generic boot option iommu.dma_mode Zhen Lei
  2019-04-09 12:53 ` [PATCH v5 2/6] iommu: add build options corresponding to iommu.dma_mode Zhen Lei
@ 2019-04-09 12:53 ` Zhen Lei
  2019-04-09 12:53 ` [PATCH v5 4/6] s390/pci: add support for generic boot option iommu.dma_mode Zhen Lei
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Zhen Lei @ 2019-04-09 12:53 UTC (permalink / raw)
  To: Jean-Philippe Brucker, John Garry, Robin Murphy, Will Deacon,
	Joerg Roedel, Jonathan Corbet, linux-doc, Sebastian Ott,
	Gerald Schaefer, Martin Schwidefsky, Heiko Carstens,
	Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Tony Luck, Fenghua Yu, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, David Woodhouse, iommu,
	linux-kernel, linux-s390, linuxppc-dev, x86, linux-ia64
  Cc: Zhen Lei, Hanjun Guo

Also add IOMMU_DMA_MODE_IS_{STRICT|LAZT|PASSTHROUGH}() to make the code
looks cleaner.

There is no functional change, just prepare for the following patches.

Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
---
 drivers/iommu/iommu.c | 18 ++++++++++++++----
 include/linux/iommu.h | 18 ++++++++++++++++++
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index f4171bf4b46eaeb..86239dd46003fd4 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -195,6 +195,17 @@ static int __init iommu_dma_mode_setup(char *str)
 }
 early_param("iommu.dma_mode", iommu_dma_mode_setup);
 
+int iommu_default_dma_mode_get(void)
+{
+	return iommu_default_dma_mode;
+}
+
+void iommu_default_dma_mode_set(int mode)
+{
+	WARN_ON(mode > IOMMU_DMA_MODE_PASSTHROUGH);
+	iommu_default_dma_mode = mode;
+}
+
 static ssize_t iommu_group_attr_show(struct kobject *kobj,
 				     struct attribute *__attr, char *buf)
 {
@@ -1136,9 +1147,8 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev)
 	 */
 	if (!group->default_domain) {
 		struct iommu_domain *dom;
-		int def_domain_type =
-			(iommu_default_dma_mode == IOMMU_DMA_MODE_PASSTHROUGH)
-			? IOMMU_DOMAIN_IDENTITY : IOMMU_DOMAIN_DMA;
+		int def_domain_type = IOMMU_DMA_MODE_IS_PASSTHROUGH() ?
+				IOMMU_DOMAIN_IDENTITY : IOMMU_DOMAIN_DMA;
 
 		dom = __iommu_domain_alloc(dev->bus, def_domain_type);
 		if (!dom && def_domain_type != IOMMU_DOMAIN_DMA) {
@@ -1154,7 +1164,7 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev)
 		if (!group->domain)
 			group->domain = dom;
 
-		if (dom && (iommu_default_dma_mode == IOMMU_DMA_MODE_LAZY)) {
+		if (dom && IOMMU_DMA_MODE_IS_LAZY()) {
 			int attr = 1;
 			iommu_domain_set_attr(dom,
 					      DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE,
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index c3f4e3416176496..3668a8b3846996a 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -46,6 +46,12 @@
 #define IOMMU_DMA_MODE_STRICT		0x0
 #define IOMMU_DMA_MODE_LAZY		0x1
 #define IOMMU_DMA_MODE_PASSTHROUGH	0x2
+#define IOMMU_DMA_MODE_IS_STRICT() \
+		(iommu_default_dma_mode_get() == IOMMU_DMA_MODE_STRICT)
+#define IOMMU_DMA_MODE_IS_LAZY() \
+		(iommu_default_dma_mode_get() == IOMMU_DMA_MODE_LAZY)
+#define IOMMU_DMA_MODE_IS_PASSTHROUGH() \
+		(iommu_default_dma_mode_get() == IOMMU_DMA_MODE_PASSTHROUGH)
 
 struct iommu_ops;
 struct iommu_group;
@@ -421,6 +427,9 @@ static inline void dev_iommu_fwspec_set(struct device *dev,
 int iommu_probe_device(struct device *dev);
 void iommu_release_device(struct device *dev);
 
+extern int iommu_default_dma_mode_get(void);
+extern void iommu_default_dma_mode_set(int mode);
+
 #else /* CONFIG_IOMMU_API */
 
 struct iommu_ops {};
@@ -705,6 +714,15 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
 	return NULL;
 }
 
+static inline int iommu_default_dma_mode_get(void)
+{
+	return IOMMU_DMA_MODE_PASSTHROUGH;
+}
+
+static inline void iommu_default_dma_mode_set(int mode)
+{
+}
+
 #endif /* CONFIG_IOMMU_API */
 
 #ifdef CONFIG_IOMMU_DEBUGFS
-- 
1.8.3



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v5 4/6] s390/pci: add support for generic boot option iommu.dma_mode
  2019-04-09 12:53 [PATCH v5 0/6] add generic boot option for IOMMU dma mode Zhen Lei
                   ` (2 preceding siblings ...)
  2019-04-09 12:53 ` [PATCH v5 3/6] iommu: add iommu_default_dma_mode_get/set() helper Zhen Lei
@ 2019-04-09 12:53 ` Zhen Lei
  2019-04-10 11:46   ` Sebastian Ott
  2019-04-09 12:53 ` [PATCH v5 5/6] powernv/iommu: " Zhen Lei
  2019-04-09 12:53 ` [PATCH v5 6/6] x86/iommu: " Zhen Lei
  5 siblings, 1 reply; 14+ messages in thread
From: Zhen Lei @ 2019-04-09 12:53 UTC (permalink / raw)
  To: Jean-Philippe Brucker, John Garry, Robin Murphy, Will Deacon,
	Joerg Roedel, Jonathan Corbet, linux-doc, Sebastian Ott,
	Gerald Schaefer, Martin Schwidefsky, Heiko Carstens,
	Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Tony Luck, Fenghua Yu, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, David Woodhouse, iommu,
	linux-kernel, linux-s390, linuxppc-dev, x86, linux-ia64
  Cc: Zhen Lei, Hanjun Guo

s390_iommu=strict is equivalent to iommu.dma_mode=strict.

Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
---
 Documentation/admin-guide/kernel-parameters.txt |  6 +++---
 arch/s390/pci/pci_dma.c                         | 14 +++++++-------
 drivers/iommu/Kconfig                           |  1 +
 3 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 92d1b3151d003c2..ab8e3c4798c0a2a 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1815,9 +1815,9 @@
 			options(such as CONFIG_IOMMU_DEFAULT_PASSTHROUGH) to
 			choose which mode to be used.
 			Note: For historical reasons, ARM64/S390/PPC/X86 have
-			their specific options. Currently, only ARM64 support
-			this boot option, and hope other ARCHs to use this as
-			generic boot option.
+			their specific options. Currently, only ARM64/S390
+			support this boot option, and hope other ARCHs to use
+			this as generic boot option.
 		passthrough
 			Configure DMA to bypass the IOMMU by default.
 		lazy
diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c
index 9e52d1527f71495..f658ca41547eed5 100644
--- a/arch/s390/pci/pci_dma.c
+++ b/arch/s390/pci/pci_dma.c
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/export.h>
+#include <linux/iommu.h>
 #include <linux/iommu-helper.h>
 #include <linux/dma-mapping.h>
 #include <linux/vmalloc.h>
@@ -17,7 +18,6 @@
 
 static struct kmem_cache *dma_region_table_cache;
 static struct kmem_cache *dma_page_table_cache;
-static int s390_iommu_strict;
 
 static int zpci_refresh_global(struct zpci_dev *zdev)
 {
@@ -193,13 +193,13 @@ static int __dma_purge_tlb(struct zpci_dev *zdev, dma_addr_t dma_addr,
 		if (!zdev->tlb_refresh)
 			return 0;
 	} else {
-		if (!s390_iommu_strict)
+		if (!IOMMU_DMA_MODE_IS_STRICT())
 			return 0;
 	}
 
 	ret = zpci_refresh_trans((u64) zdev->fh << 32, dma_addr,
 				 PAGE_ALIGN(size));
-	if (ret == -ENOMEM && !s390_iommu_strict) {
+	if (ret == -ENOMEM && !IOMMU_DMA_MODE_IS_STRICT()) {
 		/* enable the hypervisor to free some resources */
 		if (zpci_refresh_global(zdev))
 			goto out;
@@ -278,7 +278,7 @@ static dma_addr_t dma_alloc_address(struct device *dev, int size)
 	spin_lock_irqsave(&zdev->iommu_bitmap_lock, flags);
 	offset = __dma_alloc_iommu(dev, zdev->next_bit, size);
 	if (offset == -1) {
-		if (!s390_iommu_strict) {
+		if (!IOMMU_DMA_MODE_IS_STRICT()) {
 			/* global flush before DMA addresses are reused */
 			if (zpci_refresh_global(zdev))
 				goto out_error;
@@ -313,7 +313,7 @@ static void dma_free_address(struct device *dev, dma_addr_t dma_addr, int size)
 	if (!zdev->iommu_bitmap)
 		goto out;
 
-	if (s390_iommu_strict)
+	if (IOMMU_DMA_MODE_IS_STRICT())
 		bitmap_clear(zdev->iommu_bitmap, offset, size);
 	else
 		bitmap_set(zdev->lazy_bitmap, offset, size);
@@ -584,7 +584,7 @@ int zpci_dma_init_device(struct zpci_dev *zdev)
 		rc = -ENOMEM;
 		goto free_dma_table;
 	}
-	if (!s390_iommu_strict) {
+	if (!IOMMU_DMA_MODE_IS_STRICT()) {
 		zdev->lazy_bitmap = vzalloc(zdev->iommu_pages / 8);
 		if (!zdev->lazy_bitmap) {
 			rc = -ENOMEM;
@@ -675,7 +675,7 @@ void zpci_dma_exit(void)
 static int __init s390_iommu_setup(char *str)
 {
 	if (!strncmp(str, "strict", 6))
-		s390_iommu_strict = 1;
+		iommu_default_dma_mode_set(IOMMU_DMA_MODE_STRICT);
 	return 0;
 }
 
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 1986f9767da488b..b7173b106cd816a 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -77,6 +77,7 @@ config IOMMU_DEBUGFS
 choice
 	prompt "IOMMU dma mode"
 	depends on IOMMU_API
+	default IOMMU_DEFAULT_LAZY if S390_IOMMU
 	default IOMMU_DEFAULT_STRICT
 	help
 	  This option allows IOMMU dma mode to be chose at build time, to
-- 
1.8.3



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v5 5/6] powernv/iommu: add support for generic boot option iommu.dma_mode
  2019-04-09 12:53 [PATCH v5 0/6] add generic boot option for IOMMU dma mode Zhen Lei
                   ` (3 preceding siblings ...)
  2019-04-09 12:53 ` [PATCH v5 4/6] s390/pci: add support for generic boot option iommu.dma_mode Zhen Lei
@ 2019-04-09 12:53 ` Zhen Lei
  2019-04-09 12:53 ` [PATCH v5 6/6] x86/iommu: " Zhen Lei
  5 siblings, 0 replies; 14+ messages in thread
From: Zhen Lei @ 2019-04-09 12:53 UTC (permalink / raw)
  To: Jean-Philippe Brucker, John Garry, Robin Murphy, Will Deacon,
	Joerg Roedel, Jonathan Corbet, linux-doc, Sebastian Ott,
	Gerald Schaefer, Martin Schwidefsky, Heiko Carstens,
	Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Tony Luck, Fenghua Yu, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, David Woodhouse, iommu,
	linux-kernel, linux-s390, linuxppc-dev, x86, linux-ia64
  Cc: Zhen Lei, Hanjun Guo

iommu=nobypass can be replaced with iommu.dma_mode=strict.

Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
---
 Documentation/admin-guide/kernel-parameters.txt | 2 +-
 arch/powerpc/platforms/powernv/pci-ioda.c       | 5 ++---
 drivers/iommu/Kconfig                           | 1 +
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index ab8e3c4798c0a2a..176f96032d9d62a 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1815,7 +1815,7 @@
 			options(such as CONFIG_IOMMU_DEFAULT_PASSTHROUGH) to
 			choose which mode to be used.
 			Note: For historical reasons, ARM64/S390/PPC/X86 have
-			their specific options. Currently, only ARM64/S390
+			their specific options. Currently, only ARM64/S390/PPC
 			support this boot option, and hope other ARCHs to use
 			this as generic boot option.
 		passthrough
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 3ead4c237ed0ec9..8862885d866418f 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -85,7 +85,6 @@ void pe_level_printk(const struct pnv_ioda_pe *pe, const char *level,
 	va_end(args);
 }
 
-static bool pnv_iommu_bypass_disabled __read_mostly;
 static bool pci_reset_phbs __read_mostly;
 
 static int __init iommu_setup(char *str)
@@ -95,7 +94,7 @@ static int __init iommu_setup(char *str)
 
 	while (*str) {
 		if (!strncmp(str, "nobypass", 8)) {
-			pnv_iommu_bypass_disabled = true;
+			iommu_default_dma_mode_set(IOMMU_DMA_MODE_STRICT);
 			pr_info("PowerNV: IOMMU bypass window disabled.\n");
 			break;
 		}
@@ -2456,7 +2455,7 @@ static long pnv_pci_ioda2_setup_default_config(struct pnv_ioda_pe *pe)
 		return rc;
 	}
 
-	if (!pnv_iommu_bypass_disabled)
+	if (IOMMU_DMA_MODE_IS_PASSTHROUGH())
 		pnv_pci_ioda2_set_bypass(pe, true);
 
 	return 0;
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index b7173b106cd816a..5dca666b22e6cd5 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -77,6 +77,7 @@ config IOMMU_DEBUGFS
 choice
 	prompt "IOMMU dma mode"
 	depends on IOMMU_API
+	default IOMMU_DEFAULT_PASSTHROUGH if (PPC_POWERNV && PCI)
 	default IOMMU_DEFAULT_LAZY if S390_IOMMU
 	default IOMMU_DEFAULT_STRICT
 	help
-- 
1.8.3



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v5 6/6] x86/iommu: add support for generic boot option iommu.dma_mode
  2019-04-09 12:53 [PATCH v5 0/6] add generic boot option for IOMMU dma mode Zhen Lei
                   ` (4 preceding siblings ...)
  2019-04-09 12:53 ` [PATCH v5 5/6] powernv/iommu: " Zhen Lei
@ 2019-04-09 12:53 ` Zhen Lei
  5 siblings, 0 replies; 14+ messages in thread
From: Zhen Lei @ 2019-04-09 12:53 UTC (permalink / raw)
  To: Jean-Philippe Brucker, John Garry, Robin Murphy, Will Deacon,
	Joerg Roedel, Jonathan Corbet, linux-doc, Sebastian Ott,
	Gerald Schaefer, Martin Schwidefsky, Heiko Carstens,
	Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Tony Luck, Fenghua Yu, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, David Woodhouse, iommu,
	linux-kernel, linux-s390, linuxppc-dev, x86, linux-ia64
  Cc: Zhen Lei, Hanjun Guo

The following equivalence or replacement relationship exists:
iommu=pt <--> iommu.dma_mode=passthrough.
iommu=nopt can be replaced with iommu.dma_mode=lazy.
intel_iommu=strict <--> iommu.dma_mode=strict.
amd_iommu=fullflush <--> iommu.dma_mode=strict.

Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
---
 Documentation/admin-guide/kernel-parameters.txt |  6 ++---
 arch/ia64/include/asm/iommu.h                   |  2 --
 arch/ia64/kernel/pci-dma.c                      |  2 --
 arch/x86/include/asm/iommu.h                    |  1 -
 arch/x86/kernel/pci-dma.c                       | 35 ++++++++++++-------------
 drivers/iommu/Kconfig                           |  2 +-
 drivers/iommu/amd_iommu.c                       | 10 +++----
 drivers/iommu/amd_iommu_init.c                  |  4 +--
 drivers/iommu/amd_iommu_types.h                 |  6 -----
 drivers/iommu/intel-iommu.c                     |  9 +++----
 10 files changed, 31 insertions(+), 46 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 176f96032d9d62a..ca6edc529d6a614 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1815,9 +1815,9 @@
 			options(such as CONFIG_IOMMU_DEFAULT_PASSTHROUGH) to
 			choose which mode to be used.
 			Note: For historical reasons, ARM64/S390/PPC/X86 have
-			their specific options. Currently, only ARM64/S390/PPC
-			support this boot option, and hope other ARCHs to use
-			this as generic boot option.
+			their specific options, but strongly recommended switch
+			to use this one, the new ARCHs should use this generic
+			boot option.
 		passthrough
 			Configure DMA to bypass the IOMMU by default.
 		lazy
diff --git a/arch/ia64/include/asm/iommu.h b/arch/ia64/include/asm/iommu.h
index 7429a72f3f92199..92aceef63710861 100644
--- a/arch/ia64/include/asm/iommu.h
+++ b/arch/ia64/include/asm/iommu.h
@@ -8,10 +8,8 @@
 extern void no_iommu_init(void);
 #ifdef	CONFIG_INTEL_IOMMU
 extern int force_iommu, no_iommu;
-extern int iommu_pass_through;
 extern int iommu_detected;
 #else
-#define iommu_pass_through	(0)
 #define no_iommu		(1)
 #define iommu_detected		(0)
 #endif
diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c
index fe988c49f01ce6a..f5d49cd3fbb01a9 100644
--- a/arch/ia64/kernel/pci-dma.c
+++ b/arch/ia64/kernel/pci-dma.c
@@ -22,8 +22,6 @@
 int force_iommu __read_mostly;
 #endif
 
-int iommu_pass_through;
-
 static int __init pci_iommu_init(void)
 {
 	if (iommu_detected)
diff --git a/arch/x86/include/asm/iommu.h b/arch/x86/include/asm/iommu.h
index baedab8ac5385f7..b91623d521d9f0f 100644
--- a/arch/x86/include/asm/iommu.h
+++ b/arch/x86/include/asm/iommu.h
@@ -4,7 +4,6 @@
 
 extern int force_iommu, no_iommu;
 extern int iommu_detected;
-extern int iommu_pass_through;
 
 /* 10 seconds */
 #define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000)
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index d460998ae828514..fc64928e47cb860 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -6,6 +6,7 @@
 #include <linux/memblock.h>
 #include <linux/gfp.h>
 #include <linux/pci.h>
+#include <linux/iommu.h>
 
 #include <asm/proto.h>
 #include <asm/dma.h>
@@ -34,21 +35,6 @@
 /* Set this to 1 if there is a HW IOMMU in the system */
 int iommu_detected __read_mostly = 0;
 
-/*
- * This variable becomes 1 if iommu=pt is passed on the kernel command line.
- * If this variable is 1, IOMMU implementations do no DMA translation for
- * devices and allow every device to access to whole physical memory. This is
- * useful if a user wants to use an IOMMU only for KVM device assignment to
- * guests and not for driver dma translation.
- * It is also possible to disable by default in kernel config, and enable with
- * iommu=nopt at boot time.
- */
-#ifdef CONFIG_IOMMU_DEFAULT_PASSTHROUGH
-int iommu_pass_through __read_mostly = 1;
-#else
-int iommu_pass_through __read_mostly;
-#endif
-
 extern struct iommu_table_entry __iommu_table[], __iommu_table_end[];
 
 /* Dummy device used for NULL arguments (normally ISA). */
@@ -139,10 +125,23 @@ static __init int iommu_setup(char *p)
 		if (!strncmp(p, "soft", 4))
 			swiotlb = 1;
 #endif
+
+		/*
+		 * IOMMU implementations do no DMA translation for devices and
+		 * allow every device to access to whole physical memory. This
+		 * is useful if a user wants to use an IOMMU only for KVM
+		 * device assignment to guests and not for driver dma
+		 * translation.
+		 */
 		if (!strncmp(p, "pt", 2))
-			iommu_pass_through = 1;
-		if (!strncmp(p, "nopt", 4))
-			iommu_pass_through = 0;
+			iommu_default_dma_mode_set(IOMMU_DMA_MODE_PASSTHROUGH);
+
+		/*
+		 * The default dma mode is lazy on X86. And if dma mode is
+		 * already nopt, keep it no change.
+		 */
+		if (!strncmp(p, "nopt", 4) && IOMMU_DMA_MODE_IS_PASSTHROUGH())
+			iommu_default_dma_mode_set(IOMMU_DMA_MODE_LAZY);
 
 		gart_parse_options(p);
 
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 5dca666b22e6cd5..ace8cb467d742f9 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -78,7 +78,7 @@ choice
 	prompt "IOMMU dma mode"
 	depends on IOMMU_API
 	default IOMMU_DEFAULT_PASSTHROUGH if (PPC_POWERNV && PCI)
-	default IOMMU_DEFAULT_LAZY if S390_IOMMU
+	default IOMMU_DEFAULT_LAZY if (AMD_IOMMU || INTEL_IOMMU || S390_IOMMU)
 	default IOMMU_DEFAULT_STRICT
 	help
 	  This option allows IOMMU dma mode to be chose at build time, to
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index f7cdd2ab7f11f6c..44be42f1e887ea4 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -448,7 +448,7 @@ static int iommu_init_device(struct device *dev)
 	 * invalid address), we ignore the capability for the device so
 	 * it'll be forced to go into translation mode.
 	 */
-	if ((iommu_pass_through || !amd_iommu_force_isolation) &&
+	if ((IOMMU_DMA_MODE_IS_PASSTHROUGH() || !amd_iommu_force_isolation) &&
 	    dev_is_pci(dev) && pci_iommuv2_capable(to_pci_dev(dev))) {
 		struct amd_iommu *iommu;
 
@@ -2274,7 +2274,7 @@ static int amd_iommu_add_device(struct device *dev)
 
 	BUG_ON(!dev_data);
 
-	if (iommu_pass_through || dev_data->iommu_v2)
+	if (IOMMU_DMA_MODE_IS_PASSTHROUGH() || dev_data->iommu_v2)
 		iommu_request_dm_for_dev(dev);
 
 	/* Domains are initialized for this device - have a look what we ended up with */
@@ -2479,7 +2479,7 @@ static void __unmap_single(struct dma_ops_domain *dma_dom,
 		start += PAGE_SIZE;
 	}
 
-	if (amd_iommu_unmap_flush) {
+	if (IOMMU_DMA_MODE_IS_STRICT()) {
 		domain_flush_tlb(&dma_dom->domain);
 		domain_flush_complete(&dma_dom->domain);
 		dma_ops_free_iova(dma_dom, dma_addr, pages);
@@ -2853,10 +2853,10 @@ int __init amd_iommu_init_api(void)
 
 int __init amd_iommu_init_dma_ops(void)
 {
-	swiotlb        = (iommu_pass_through || sme_me_mask) ? 1 : 0;
+	swiotlb = (IOMMU_DMA_MODE_IS_PASSTHROUGH() || sme_me_mask) ? 1 : 0;
 	iommu_detected = 1;
 
-	if (amd_iommu_unmap_flush)
+	if (IOMMU_DMA_MODE_IS_STRICT())
 		pr_info("IO/TLB flush on unmap enabled\n");
 	else
 		pr_info("Lazy IO/TLB flushing enabled\n");
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 1b1378619fc9ec2..eae18aae2bafd39 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -166,8 +166,6 @@ struct ivmd_header {
 					   to handle */
 LIST_HEAD(amd_iommu_unity_map);		/* a list of required unity mappings
 					   we find in ACPI */
-bool amd_iommu_unmap_flush;		/* if true, flush on every unmap */
-
 LIST_HEAD(amd_iommu_list);		/* list of all AMD IOMMUs in the
 					   system */
 
@@ -2857,7 +2855,7 @@ static int __init parse_amd_iommu_options(char *str)
 {
 	for (; *str; ++str) {
 		if (strncmp(str, "fullflush", 9) == 0)
-			amd_iommu_unmap_flush = true;
+			iommu_default_dma_mode_set(IOMMU_DMA_MODE_STRICT);
 		if (strncmp(str, "off", 3) == 0)
 			amd_iommu_disabled = true;
 		if (strncmp(str, "force_isolation", 15) == 0)
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index 87965e4d964771b..724182f158523a1 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -743,12 +743,6 @@ struct unity_map_entry {
 /* allocation bitmap for domain ids */
 extern unsigned long *amd_iommu_pd_alloc_bitmap;
 
-/*
- * If true, the addresses will be flushed on unmap time, not when
- * they are reused
- */
-extern bool amd_iommu_unmap_flush;
-
 /* Smallest max PASID supported by any IOMMU in the system */
 extern u32 amd_iommu_max_pasid;
 
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 28cb713d728ceef..57203f895382831 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -362,7 +362,6 @@ static int domain_detach_iommu(struct dmar_domain *domain,
 
 static int dmar_map_gfx = 1;
 static int dmar_forcedac;
-static int intel_iommu_strict;
 static int intel_iommu_superpage = 1;
 static int intel_iommu_sm;
 static int iommu_identity_mapping;
@@ -453,7 +452,7 @@ static int __init intel_iommu_setup(char *str)
 			dmar_forcedac = 1;
 		} else if (!strncmp(str, "strict", 6)) {
 			pr_info("Disable batched IOTLB flush\n");
-			intel_iommu_strict = 1;
+			iommu_default_dma_mode_set(IOMMU_DMA_MODE_STRICT);
 		} else if (!strncmp(str, "sp_off", 6)) {
 			pr_info("Disable supported super page\n");
 			intel_iommu_superpage = 0;
@@ -3408,7 +3407,7 @@ static int __init init_dmars(void)
 		iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
 	}
 
-	if (iommu_pass_through)
+	if (IOMMU_DMA_MODE_IS_PASSTHROUGH())
 		iommu_identity_mapping |= IDENTMAP_ALL;
 
 #ifdef CONFIG_INTEL_IOMMU_BROKEN_GFX_WA
@@ -3749,7 +3748,7 @@ static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size)
 
 	freelist = domain_unmap(domain, start_pfn, last_pfn);
 
-	if (intel_iommu_strict) {
+	if (IOMMU_DMA_MODE_IS_STRICT()) {
 		iommu_flush_iotlb_psi(iommu, domain, start_pfn,
 				      nrpages, !freelist, 0);
 		/* free iova */
@@ -5460,7 +5459,7 @@ static void quirk_calpella_no_shadow_gtt(struct pci_dev *dev)
 	} else if (dmar_map_gfx) {
 		/* we have to ensure the gfx device is idle before we flush */
 		pci_info(dev, "Disabling batched IOTLB flush on Ironlake\n");
-		intel_iommu_strict = 1;
+		iommu_default_dma_mode_set(IOMMU_DMA_MODE_STRICT);
        }
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt);
-- 
1.8.3



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v5 4/6] s390/pci: add support for generic boot option iommu.dma_mode
  2019-04-09 12:53 ` [PATCH v5 4/6] s390/pci: add support for generic boot option iommu.dma_mode Zhen Lei
@ 2019-04-10 11:46   ` Sebastian Ott
  0 siblings, 0 replies; 14+ messages in thread
From: Sebastian Ott @ 2019-04-10 11:46 UTC (permalink / raw)
  To: Zhen Lei
  Cc: Jean-Philippe Brucker, John Garry, Robin Murphy, Will Deacon,
	Joerg Roedel, Jonathan Corbet, linux-doc, Gerald Schaefer,
	Martin Schwidefsky, Heiko Carstens, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, Tony Luck, Fenghua Yu,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	David Woodhouse, iommu, linux-kernel, linux-s390, linuxppc-dev,
	x86, linux-ia64, Hanjun Guo

On Tue, 9 Apr 2019, Zhen Lei wrote:
> s390_iommu=strict is equivalent to iommu.dma_mode=strict.
> 
> Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>

Acked-by: Sebastian Ott <sebott@linux.ibm.com>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v5 1/6] iommu: add generic boot option iommu.dma_mode
  2019-04-09 12:53 ` [PATCH v5 1/6] iommu: add generic boot option iommu.dma_mode Zhen Lei
@ 2019-04-12 10:26   ` John Garry
  2019-04-12 13:11     ` Robin Murphy
  2019-04-12 11:16   ` Joerg Roedel
  1 sibling, 1 reply; 14+ messages in thread
From: John Garry @ 2019-04-12 10:26 UTC (permalink / raw)
  To: Zhen Lei, Jean-Philippe Brucker, Robin Murphy, Will Deacon,
	Joerg Roedel, Jonathan Corbet, linux-doc, Sebastian Ott,
	Gerald Schaefer, Martin Schwidefsky, Heiko Carstens,
	Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Tony Luck, Fenghua Yu, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, David Woodhouse, iommu,
	linux-kernel, linux-s390, linuxppc-dev, x86, linux-ia64
  Cc: Hanjun Guo

On 09/04/2019 13:53, Zhen Lei wrote:
> Currently the IOMMU dma contains 3 modes: passthrough, lazy, strict. The
> passthrough mode bypass the IOMMU, the lazy mode defer the invalidation
> of hardware TLBs, and the strict mode invalidate IOMMU hardware TLBs
> synchronously. The three modes are mutually exclusive. But the current
> boot options are confused, such as: iommu.passthrough and iommu.strict,
> because they are no good to be coexist. So add iommu.dma_mode.
>
> Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
> ---
>  Documentation/admin-guide/kernel-parameters.txt | 19 ++++++++
>  drivers/iommu/iommu.c                           | 59 ++++++++++++++++++++-----
>  include/linux/iommu.h                           |  5 +++
>  3 files changed, 71 insertions(+), 12 deletions(-)
>
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index 2b8ee90bb64470d..f7766f8ac8b9084 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -1811,6 +1811,25 @@
>  			1 - Bypass the IOMMU for DMA.
>  			unset - Use value of CONFIG_IOMMU_DEFAULT_PASSTHROUGH.
>
> +	iommu.dma_mode= Configure default dma mode. if unset, use the value
> +			of CONFIG_IOMMU_DEFAULT_PASSTHROUGH to determine
> +			passthrough or not.

To me, for unset it's unclear what we default to. So if unset and also 
CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set, do we get lazy or strict 
mode? (note: I'm ignoring backwards compatibility and interaction of 
iommu.strict and .passthorugh also, more below).

Could we considering introducing config DEFAULT_IOMMU_DMA_MODE, similar 
to DEFAULT_IOSCHED?

> +			Note: For historical reasons, ARM64/S390/PPC/X86 have
> +			their specific options. Currently, only ARM64 support
> +			this boot option, and hope other ARCHs to use this as
> +			generic boot option.
> +		passthrough
> +			Configure DMA to bypass the IOMMU by default.
> +		lazy
> +			Request that DMA unmap operations use deferred
> +			invalidation of hardware TLBs, for increased
> +			throughput at the cost of reduced device isolation.
> +			Will fall back to strict mode if not supported by
> +			the relevant IOMMU driver.
> +		strict
> +			DMA unmap operations invalidate IOMMU hardware TLBs
> +			synchronously.
> +
>  	io7=		[HW] IO7 for Marvel based alpha systems
>  			See comment before marvel_specify_io7 in
>  			arch/alpha/kernel/core_marvel.c.
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 109de67d5d727c2..df1ce8e22385b48 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -38,12 +38,13 @@
>
>  static struct kset *iommu_group_kset;
>  static DEFINE_IDA(iommu_group_ida);
> +
>  #ifdef CONFIG_IOMMU_DEFAULT_PASSTHROUGH
> -static unsigned int iommu_def_domain_type = IOMMU_DOMAIN_IDENTITY;
> +#define IOMMU_DEFAULT_DMA_MODE		IOMMU_DMA_MODE_PASSTHROUGH
>  #else
> -static unsigned int iommu_def_domain_type = IOMMU_DOMAIN_DMA;
> +#define IOMMU_DEFAULT_DMA_MODE		IOMMU_DMA_MODE_STRICT
>  #endif
> -static bool iommu_dma_strict __read_mostly = true;
> +static int iommu_default_dma_mode __read_mostly = IOMMU_DEFAULT_DMA_MODE;
>
>  struct iommu_callback_data {
>  	const struct iommu_ops *ops;
> @@ -147,20 +148,51 @@ static int __init iommu_set_def_domain_type(char *str)
>  	int ret;
>
>  	ret = kstrtobool(str, &pt);
> -	if (ret)
> -		return ret;
> +	if (!ret && pt)
> +		iommu_default_dma_mode = IOMMU_DMA_MODE_PASSTHROUGH;
>
> -	iommu_def_domain_type = pt ? IOMMU_DOMAIN_IDENTITY : IOMMU_DOMAIN_DMA;
> -	return 0;
> +	return ret;
>  }
>  early_param("iommu.passthrough", iommu_set_def_domain_type);
>
>  static int __init iommu_dma_setup(char *str)
>  {
> -	return kstrtobool(str, &iommu_dma_strict);
> +	bool strict;
> +	int ret;
> +
> +	ret = kstrtobool(str, &strict);
> +	if (!ret)
> +		iommu_default_dma_mode = strict ?
> +				IOMMU_DMA_MODE_STRICT : IOMMU_DMA_MODE_LAZY;
> +
> +	return ret;
>  }
>  early_param("iommu.strict", iommu_dma_setup);
>
> +static int __init iommu_dma_mode_setup(char *str)
> +{
> +	if (!str)
> +		goto fail;
> +
> +	if (!strncmp(str, "passthrough", 11))
> +		iommu_default_dma_mode = IOMMU_DMA_MODE_PASSTHROUGH;
> +	else if (!strncmp(str, "lazy", 4))
> +		iommu_default_dma_mode = IOMMU_DMA_MODE_LAZY;
> +	else if (!strncmp(str, "strict", 6))
> +		iommu_default_dma_mode = IOMMU_DMA_MODE_STRICT;
> +	else
> +		goto fail;
> +
> +	pr_info("Force dma mode to be %d\n", iommu_default_dma_mode);

What happens if the cmdline option iommu.dma_mode is passed multiple 
times? We get mutliple - possibily conflicting - prints, right?

And do we need to have backwards compatibility, such that the setting 
for iommu.strict or iommu.passthrough trumps iommu.dma_mode, regardless 
of order?

> +
> +	return 0;
> +
> +fail:
> +	pr_debug("Boot option iommu.dma_mode is incorrect, ignored\n");
> +	return -EINVAL;
> +}
> +early_param("iommu.dma_mode", iommu_dma_mode_setup);
> +
>  static ssize_t iommu_group_attr_show(struct kobject *kobj,
>  				     struct attribute *__attr, char *buf)
>  {
> @@ -1102,14 +1134,17 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev)
>  	 */
>  	if (!group->default_domain) {
>  		struct iommu_domain *dom;
> +		int def_domain_type =
> +			(iommu_default_dma_mode == IOMMU_DMA_MODE_PASSTHROUGH)
> +			? IOMMU_DOMAIN_IDENTITY : IOMMU_DOMAIN_DMA;
>
> -		dom = __iommu_domain_alloc(dev->bus, iommu_def_domain_type);
> -		if (!dom && iommu_def_domain_type != IOMMU_DOMAIN_DMA) {
> +		dom = __iommu_domain_alloc(dev->bus, def_domain_type);
> +		if (!dom && def_domain_type != IOMMU_DOMAIN_DMA) {
>  			dom = __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_DMA);
>  			if (dom) {
>  				dev_warn(dev,
>  					 "failed to allocate default IOMMU domain of type %u; falling back to IOMMU_DOMAIN_DMA",
> -					 iommu_def_domain_type);
> +					 def_domain_type);
>  			}
>  		}
>
> @@ -1117,7 +1152,7 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev)
>  		if (!group->domain)
>  			group->domain = dom;
>
> -		if (dom && !iommu_dma_strict) {
> +		if (dom && (iommu_default_dma_mode == IOMMU_DMA_MODE_LAZY)) {
>  			int attr = 1;
>  			iommu_domain_set_attr(dom,
>  					      DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE,
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index ffbbc7e39ceeba3..c3f4e3416176496 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -42,6 +42,11 @@
>   */
>  #define IOMMU_PRIV	(1 << 5)
>
> +
> +#define IOMMU_DMA_MODE_STRICT		0x0
> +#define IOMMU_DMA_MODE_LAZY		0x1
> +#define IOMMU_DMA_MODE_PASSTHROUGH	0x2
> +
>  struct iommu_ops;
>  struct iommu_group;
>  struct bus_type;
>



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v5 1/6] iommu: add generic boot option iommu.dma_mode
  2019-04-09 12:53 ` [PATCH v5 1/6] iommu: add generic boot option iommu.dma_mode Zhen Lei
  2019-04-12 10:26   ` John Garry
@ 2019-04-12 11:16   ` Joerg Roedel
  2019-04-23  2:45     ` Leizhen (ThunderTown)
  1 sibling, 1 reply; 14+ messages in thread
From: Joerg Roedel @ 2019-04-12 11:16 UTC (permalink / raw)
  To: Zhen Lei
  Cc: Jean-Philippe Brucker, John Garry, Robin Murphy, Will Deacon,
	Jonathan Corbet, linux-doc, Sebastian Ott, Gerald Schaefer,
	Martin Schwidefsky, Heiko Carstens, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, Tony Luck, Fenghua Yu,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	David Woodhouse, iommu, linux-kernel, linux-s390, linuxppc-dev,
	x86, linux-ia64, Hanjun Guo

On Tue, Apr 09, 2019 at 08:53:03PM +0800, Zhen Lei wrote:
> +static int __init iommu_dma_mode_setup(char *str)
> +{
> +	if (!str)
> +		goto fail;
> +
> +	if (!strncmp(str, "passthrough", 11))
> +		iommu_default_dma_mode = IOMMU_DMA_MODE_PASSTHROUGH;
> +	else if (!strncmp(str, "lazy", 4))
> +		iommu_default_dma_mode = IOMMU_DMA_MODE_LAZY;
> +	else if (!strncmp(str, "strict", 6))
> +		iommu_default_dma_mode = IOMMU_DMA_MODE_STRICT;
> +	else
> +		goto fail;
> +
> +	pr_info("Force dma mode to be %d\n", iommu_default_dma_mode);

Printing a number is not very desriptive or helpful to the user. Please
print the name of the mode instead.


Regards,

	Joerg

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v5 1/6] iommu: add generic boot option iommu.dma_mode
  2019-04-12 10:26   ` John Garry
@ 2019-04-12 13:11     ` Robin Murphy
  2019-04-16 15:21       ` Will Deacon
  0 siblings, 1 reply; 14+ messages in thread
From: Robin Murphy @ 2019-04-12 13:11 UTC (permalink / raw)
  To: John Garry, Zhen Lei, Jean-Philippe Brucker, Will Deacon,
	Joerg Roedel, Jonathan Corbet, linux-doc, Sebastian Ott,
	Gerald Schaefer, Martin Schwidefsky, Heiko Carstens,
	Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Tony Luck, Fenghua Yu, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H . Peter Anvin, David Woodhouse, iommu,
	linux-kernel, linux-s390, linuxppc-dev, x86, linux-ia64
  Cc: Hanjun Guo

On 12/04/2019 11:26, John Garry wrote:
> On 09/04/2019 13:53, Zhen Lei wrote:
>> Currently the IOMMU dma contains 3 modes: passthrough, lazy, strict. The
>> passthrough mode bypass the IOMMU, the lazy mode defer the invalidation
>> of hardware TLBs, and the strict mode invalidate IOMMU hardware TLBs
>> synchronously. The three modes are mutually exclusive. But the current
>> boot options are confused, such as: iommu.passthrough and iommu.strict,
>> because they are no good to be coexist. So add iommu.dma_mode.
>>
>> Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
>> ---
>>  Documentation/admin-guide/kernel-parameters.txt | 19 ++++++++
>>  drivers/iommu/iommu.c                           | 59 
>> ++++++++++++++++++++-----
>>  include/linux/iommu.h                           |  5 +++
>>  3 files changed, 71 insertions(+), 12 deletions(-)
>>
>> diff --git a/Documentation/admin-guide/kernel-parameters.txt 
>> b/Documentation/admin-guide/kernel-parameters.txt
>> index 2b8ee90bb64470d..f7766f8ac8b9084 100644
>> --- a/Documentation/admin-guide/kernel-parameters.txt
>> +++ b/Documentation/admin-guide/kernel-parameters.txt
>> @@ -1811,6 +1811,25 @@
>>              1 - Bypass the IOMMU for DMA.
>>              unset - Use value of CONFIG_IOMMU_DEFAULT_PASSTHROUGH.
>>
>> +    iommu.dma_mode= Configure default dma mode. if unset, use the value
>> +            of CONFIG_IOMMU_DEFAULT_PASSTHROUGH to determine
>> +            passthrough or not.
> 
> To me, for unset it's unclear what we default to. So if unset and also 
> CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set, do we get lazy or strict 
> mode? (note: I'm ignoring backwards compatibility and interaction of 
> iommu.strict and .passthorugh also, more below).
> 
> Could we considering introducing config DEFAULT_IOMMU_DMA_MODE, similar 
> to DEFAULT_IOSCHED?

Yes, what I was suggesting was specifically refactoring the Kconfig 
options into a single choice that controls the default (i.e. no command 
line option provided) behaviour. AFAICS it should be fairly 
straightforward to maintain the existing "strict" and "passthrough" 
options (and legacy arch-specific versions thereof) to override that 
default without introducing yet another command-line option, which I 
think we should avoid if possible.
>> +            Note: For historical reasons, ARM64/S390/PPC/X86 have
>> +            their specific options. Currently, only ARM64 support
>> +            this boot option, and hope other ARCHs to use this as
>> +            generic boot option.
>> +        passthrough
>> +            Configure DMA to bypass the IOMMU by default.
>> +        lazy
>> +            Request that DMA unmap operations use deferred
>> +            invalidation of hardware TLBs, for increased
>> +            throughput at the cost of reduced device isolation.
>> +            Will fall back to strict mode if not supported by
>> +            the relevant IOMMU driver.
>> +        strict
>> +            DMA unmap operations invalidate IOMMU hardware TLBs
>> +            synchronously.
>> +
>>      io7=        [HW] IO7 for Marvel based alpha systems
>>              See comment before marvel_specify_io7 in
>>              arch/alpha/kernel/core_marvel.c.
>> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
>> index 109de67d5d727c2..df1ce8e22385b48 100644
>> --- a/drivers/iommu/iommu.c
>> +++ b/drivers/iommu/iommu.c
>> @@ -38,12 +38,13 @@
>>
>>  static struct kset *iommu_group_kset;
>>  static DEFINE_IDA(iommu_group_ida);
>> +
>>  #ifdef CONFIG_IOMMU_DEFAULT_PASSTHROUGH
>> -static unsigned int iommu_def_domain_type = IOMMU_DOMAIN_IDENTITY;
>> +#define IOMMU_DEFAULT_DMA_MODE        IOMMU_DMA_MODE_PASSTHROUGH
>>  #else
>> -static unsigned int iommu_def_domain_type = IOMMU_DOMAIN_DMA;
>> +#define IOMMU_DEFAULT_DMA_MODE        IOMMU_DMA_MODE_STRICT
>>  #endif
>> -static bool iommu_dma_strict __read_mostly = true;
>> +static int iommu_default_dma_mode __read_mostly = 
>> IOMMU_DEFAULT_DMA_MODE;
>>
>>  struct iommu_callback_data {
>>      const struct iommu_ops *ops;
>> @@ -147,20 +148,51 @@ static int __init iommu_set_def_domain_type(char 
>> *str)
>>      int ret;
>>
>>      ret = kstrtobool(str, &pt);
>> -    if (ret)
>> -        return ret;
>> +    if (!ret && pt)
>> +        iommu_default_dma_mode = IOMMU_DMA_MODE_PASSTHROUGH;
>>
>> -    iommu_def_domain_type = pt ? IOMMU_DOMAIN_IDENTITY : 
>> IOMMU_DOMAIN_DMA;
>> -    return 0;
>> +    return ret;
>>  }
>>  early_param("iommu.passthrough", iommu_set_def_domain_type);
>>
>>  static int __init iommu_dma_setup(char *str)
>>  {
>> -    return kstrtobool(str, &iommu_dma_strict);
>> +    bool strict;
>> +    int ret;
>> +
>> +    ret = kstrtobool(str, &strict);
>> +    if (!ret)
>> +        iommu_default_dma_mode = strict ?
>> +                IOMMU_DMA_MODE_STRICT : IOMMU_DMA_MODE_LAZY;
>> +
>> +    return ret;
>>  }
>>  early_param("iommu.strict", iommu_dma_setup);
>>
>> +static int __init iommu_dma_mode_setup(char *str)
>> +{
>> +    if (!str)
>> +        goto fail;
>> +
>> +    if (!strncmp(str, "passthrough", 11))
>> +        iommu_default_dma_mode = IOMMU_DMA_MODE_PASSTHROUGH;
>> +    else if (!strncmp(str, "lazy", 4))
>> +        iommu_default_dma_mode = IOMMU_DMA_MODE_LAZY;
>> +    else if (!strncmp(str, "strict", 6))
>> +        iommu_default_dma_mode = IOMMU_DMA_MODE_STRICT;
>> +    else
>> +        goto fail;
>> +
>> +    pr_info("Force dma mode to be %d\n", iommu_default_dma_mode);
> 
> What happens if the cmdline option iommu.dma_mode is passed multiple 
> times? We get mutliple - possibily conflicting - prints, right?

Indeed; we ended up removing such prints for the existing options here, 
specifically because multiple messages seemed more likely to be 
confusing than useful.

> And do we need to have backwards compatibility, such that the setting 
> for iommu.strict or iommu.passthrough trumps iommu.dma_mode, regardless 
> of order?

As above I think it would be preferable to just keep using the existing 
options anyway. The current behaviour works out as:

iommu.passthrough |      Y	|	  N
iommu.strict	  |      x	|    Y         N
------------------|-------------|---------|--------
MODE		  | PASSTHROUGH | STRICT  |  LAZY

which seems intuitive enough that a specific dma_mode option doesn't add 
much value, and would more likely just overcomplicate things for users 
as well as our implementation.

Robin.

>> +
>> +    return 0;
>> +
>> +fail:
>> +    pr_debug("Boot option iommu.dma_mode is incorrect, ignored\n");
>> +    return -EINVAL;
>> +}
>> +early_param("iommu.dma_mode", iommu_dma_mode_setup);
>> +
>>  static ssize_t iommu_group_attr_show(struct kobject *kobj,
>>                       struct attribute *__attr, char *buf)
>>  {
>> @@ -1102,14 +1134,17 @@ struct iommu_group 
>> *iommu_group_get_for_dev(struct device *dev)
>>       */
>>      if (!group->default_domain) {
>>          struct iommu_domain *dom;
>> +        int def_domain_type =
>> +            (iommu_default_dma_mode == IOMMU_DMA_MODE_PASSTHROUGH)
>> +            ? IOMMU_DOMAIN_IDENTITY : IOMMU_DOMAIN_DMA;
>>
>> -        dom = __iommu_domain_alloc(dev->bus, iommu_def_domain_type);
>> -        if (!dom && iommu_def_domain_type != IOMMU_DOMAIN_DMA) {
>> +        dom = __iommu_domain_alloc(dev->bus, def_domain_type);
>> +        if (!dom && def_domain_type != IOMMU_DOMAIN_DMA) {
>>              dom = __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_DMA);
>>              if (dom) {
>>                  dev_warn(dev,
>>                       "failed to allocate default IOMMU domain of type 
>> %u; falling back to IOMMU_DOMAIN_DMA",
>> -                     iommu_def_domain_type);
>> +                     def_domain_type);
>>              }
>>          }
>>
>> @@ -1117,7 +1152,7 @@ struct iommu_group 
>> *iommu_group_get_for_dev(struct device *dev)
>>          if (!group->domain)
>>              group->domain = dom;
>>
>> -        if (dom && !iommu_dma_strict) {
>> +        if (dom && (iommu_default_dma_mode == IOMMU_DMA_MODE_LAZY)) {
>>              int attr = 1;
>>              iommu_domain_set_attr(dom,
>>                            DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE,
>> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
>> index ffbbc7e39ceeba3..c3f4e3416176496 100644
>> --- a/include/linux/iommu.h
>> +++ b/include/linux/iommu.h
>> @@ -42,6 +42,11 @@
>>   */
>>  #define IOMMU_PRIV    (1 << 5)
>>
>> +
>> +#define IOMMU_DMA_MODE_STRICT        0x0
>> +#define IOMMU_DMA_MODE_LAZY        0x1
>> +#define IOMMU_DMA_MODE_PASSTHROUGH    0x2
>> +
>>  struct iommu_ops;
>>  struct iommu_group;
>>  struct bus_type;
>>
> 
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v5 1/6] iommu: add generic boot option iommu.dma_mode
  2019-04-12 13:11     ` Robin Murphy
@ 2019-04-16 15:21       ` Will Deacon
  2019-04-17  2:36         ` Leizhen (ThunderTown)
  0 siblings, 1 reply; 14+ messages in thread
From: Will Deacon @ 2019-04-16 15:21 UTC (permalink / raw)
  To: Robin Murphy
  Cc: John Garry, Zhen Lei, Jean-Philippe Brucker, Joerg Roedel,
	Jonathan Corbet, linux-doc, Sebastian Ott, Gerald Schaefer,
	Martin Schwidefsky, Heiko Carstens, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, Tony Luck, Fenghua Yu,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	David Woodhouse, iommu, linux-kernel, linux-s390, linuxppc-dev,
	x86, linux-ia64, Hanjun Guo

On Fri, Apr 12, 2019 at 02:11:31PM +0100, Robin Murphy wrote:
> On 12/04/2019 11:26, John Garry wrote:
> > On 09/04/2019 13:53, Zhen Lei wrote:
> > > +static int __init iommu_dma_mode_setup(char *str)
> > > +{
> > > +    if (!str)
> > > +        goto fail;
> > > +
> > > +    if (!strncmp(str, "passthrough", 11))
> > > +        iommu_default_dma_mode = IOMMU_DMA_MODE_PASSTHROUGH;
> > > +    else if (!strncmp(str, "lazy", 4))
> > > +        iommu_default_dma_mode = IOMMU_DMA_MODE_LAZY;
> > > +    else if (!strncmp(str, "strict", 6))
> > > +        iommu_default_dma_mode = IOMMU_DMA_MODE_STRICT;
> > > +    else
> > > +        goto fail;
> > > +
> > > +    pr_info("Force dma mode to be %d\n", iommu_default_dma_mode);
> > 
> > What happens if the cmdline option iommu.dma_mode is passed multiple
> > times? We get mutliple - possibily conflicting - prints, right?
> 
> Indeed; we ended up removing such prints for the existing options here,
> specifically because multiple messages seemed more likely to be confusing
> than useful.
> 
> > And do we need to have backwards compatibility, such that the setting
> > for iommu.strict or iommu.passthrough trumps iommu.dma_mode, regardless
> > of order?
> 
> As above I think it would be preferable to just keep using the existing
> options anyway. The current behaviour works out as:
> 
> iommu.passthrough |      Y	|	  N
> iommu.strict	  |      x	|    Y         N
> ------------------|-------------|---------|--------
> MODE		  | PASSTHROUGH | STRICT  |  LAZY
> 
> which seems intuitive enough that a specific dma_mode option doesn't add
> much value, and would more likely just overcomplicate things for users as
> well as our implementation.

Agreed. We can't remove the existing options, and they do the job perfectly
well so I don't see the need to add more options on top.

Will

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v5 1/6] iommu: add generic boot option iommu.dma_mode
  2019-04-16 15:21       ` Will Deacon
@ 2019-04-17  2:36         ` Leizhen (ThunderTown)
  0 siblings, 0 replies; 14+ messages in thread
From: Leizhen (ThunderTown) @ 2019-04-17  2:36 UTC (permalink / raw)
  To: Will Deacon, Robin Murphy
  Cc: John Garry, Jean-Philippe Brucker, Joerg Roedel, Jonathan Corbet,
	linux-doc, Sebastian Ott, Gerald Schaefer, Martin Schwidefsky,
	Heiko Carstens, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Tony Luck, Fenghua Yu, Thomas Gleixner,
	Ingo Molnar, Borislav Petkov, H . Peter Anvin, David Woodhouse,
	iommu, linux-kernel, linux-s390, linuxppc-dev, x86, linux-ia64,
	Hanjun Guo



On 2019/4/16 23:21, Will Deacon wrote:
> On Fri, Apr 12, 2019 at 02:11:31PM +0100, Robin Murphy wrote:
>> On 12/04/2019 11:26, John Garry wrote:
>>> On 09/04/2019 13:53, Zhen Lei wrote:
>>>> +static int __init iommu_dma_mode_setup(char *str)
>>>> +{
>>>> +    if (!str)
>>>> +        goto fail;
>>>> +
>>>> +    if (!strncmp(str, "passthrough", 11))
>>>> +        iommu_default_dma_mode = IOMMU_DMA_MODE_PASSTHROUGH;
>>>> +    else if (!strncmp(str, "lazy", 4))
>>>> +        iommu_default_dma_mode = IOMMU_DMA_MODE_LAZY;
>>>> +    else if (!strncmp(str, "strict", 6))
>>>> +        iommu_default_dma_mode = IOMMU_DMA_MODE_STRICT;
>>>> +    else
>>>> +        goto fail;
>>>> +
>>>> +    pr_info("Force dma mode to be %d\n", iommu_default_dma_mode);
>>>
>>> What happens if the cmdline option iommu.dma_mode is passed multiple
>>> times? We get mutliple - possibily conflicting - prints, right?
>>
>> Indeed; we ended up removing such prints for the existing options here,
>> specifically because multiple messages seemed more likely to be confusing
>> than useful.

I originally intended to be compatible with X86 printing.

 		} else if (!strncmp(str, "strict", 6)) {
 			pr_info("Disable batched IOTLB flush\n");
			intel_iommu_strict = 1;
 		}

>>
>>> And do we need to have backwards compatibility, such that the setting
>>> for iommu.strict or iommu.passthrough trumps iommu.dma_mode, regardless
>>> of order?
>>
>> As above I think it would be preferable to just keep using the existing
>> options anyway. The current behaviour works out as:
>>
>> iommu.passthrough |      Y	|	  N
>> iommu.strict	  |      x	|    Y         N
>> ------------------|-------------|---------|--------
>> MODE		  | PASSTHROUGH | STRICT  |  LAZY
>>
>> which seems intuitive enough that a specific dma_mode option doesn't add
>> much value, and would more likely just overcomplicate things for users as
>> well as our implementation.
> 
> Agreed. We can't remove the existing options, and they do the job perfectly
> well so I don't see the need to add more options on top.

OK, I will remove the iommu.dma_mode option in the next version. Thanks for you three.

I didn't want to add it at first, but later found that the boot options on
each ARCH are different, then want to normalize it.

In addition, do we need to compatible the build option name IOMMU_DEFAULT_PASSTHROUGH? or
change it to IOMMU_DEFAULT_DMA_MODE_PASSTHROUGH or IOMMU_DEFAULT_MODE_PASSTHROUGH?

> 
> Will
> 
> .
> 

-- 
Thanks!
BestRegards


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v5 1/6] iommu: add generic boot option iommu.dma_mode
  2019-04-12 11:16   ` Joerg Roedel
@ 2019-04-23  2:45     ` Leizhen (ThunderTown)
  0 siblings, 0 replies; 14+ messages in thread
From: Leizhen (ThunderTown) @ 2019-04-23  2:45 UTC (permalink / raw)
  To: Joerg Roedel
  Cc: Jean-Philippe Brucker, John Garry, Robin Murphy, Will Deacon,
	Jonathan Corbet, linux-doc, Sebastian Ott, Gerald Schaefer,
	Martin Schwidefsky, Heiko Carstens, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, Tony Luck, Fenghua Yu,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, H . Peter Anvin,
	David Woodhouse, iommu, linux-kernel, linux-s390, linuxppc-dev,
	x86, linux-ia64, Hanjun Guo



On 2019/4/12 19:16, Joerg Roedel wrote:
> On Tue, Apr 09, 2019 at 08:53:03PM +0800, Zhen Lei wrote:
>> +static int __init iommu_dma_mode_setup(char *str)
>> +{
>> +	if (!str)
>> +		goto fail;
>> +
>> +	if (!strncmp(str, "passthrough", 11))
>> +		iommu_default_dma_mode = IOMMU_DMA_MODE_PASSTHROUGH;
>> +	else if (!strncmp(str, "lazy", 4))
>> +		iommu_default_dma_mode = IOMMU_DMA_MODE_LAZY;
>> +	else if (!strncmp(str, "strict", 6))
>> +		iommu_default_dma_mode = IOMMU_DMA_MODE_STRICT;
>> +	else
>> +		goto fail;
>> +
>> +	pr_info("Force dma mode to be %d\n", iommu_default_dma_mode);
> 
> Printing a number is not very desriptive or helpful to the user. Please
> print the name of the mode instead.

OK, thanks. I have given up adding iommu.dma_mode boot option according
to Robin and Will's suggestion. So these codes will be removed in v6.

> 
> 
> Regards,
> 
> 	Joerg
> 
> .
> 

-- 
Thanks!
BestRegards


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2019-04-23  2:45 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-09 12:53 [PATCH v5 0/6] add generic boot option for IOMMU dma mode Zhen Lei
2019-04-09 12:53 ` [PATCH v5 1/6] iommu: add generic boot option iommu.dma_mode Zhen Lei
2019-04-12 10:26   ` John Garry
2019-04-12 13:11     ` Robin Murphy
2019-04-16 15:21       ` Will Deacon
2019-04-17  2:36         ` Leizhen (ThunderTown)
2019-04-12 11:16   ` Joerg Roedel
2019-04-23  2:45     ` Leizhen (ThunderTown)
2019-04-09 12:53 ` [PATCH v5 2/6] iommu: add build options corresponding to iommu.dma_mode Zhen Lei
2019-04-09 12:53 ` [PATCH v5 3/6] iommu: add iommu_default_dma_mode_get/set() helper Zhen Lei
2019-04-09 12:53 ` [PATCH v5 4/6] s390/pci: add support for generic boot option iommu.dma_mode Zhen Lei
2019-04-10 11:46   ` Sebastian Ott
2019-04-09 12:53 ` [PATCH v5 5/6] powernv/iommu: " Zhen Lei
2019-04-09 12:53 ` [PATCH v5 6/6] x86/iommu: " Zhen Lei

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).