diff mbox series

[SRU,X,1/1] iommu/vt-d: Make sure IOMMUs are off when intel_iommu=off

Message ID 20190102194016.7412-2-gpiccoli@canonical.com
State New
Headers show
Series [SRU,X,1/1] iommu/vt-d: Make sure IOMMUs are off when intel_iommu=off | expand

Commit Message

Guilherme G. Piccoli Jan. 2, 2019, 7:40 p.m. UTC
From: Joerg Roedel <jroedel@suse.de>

BugLink: https://launchpad.net/bugs/1810328

When booting into a kexec kernel with intel_iommu=off, and
the previous kernel had intel_iommu=on, the IOMMU hardware
is still enabled and gets not disabled by the new kernel.

This causes the boot to fail because DMA is blocked by the
hardware. Disable the IOMMUs when we find it enabled in the
kexec kernel and boot with intel_iommu=off.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
(backported from commit 161b28aae1651aa7ad63ec14753aa8a751154340 upstream)
[gpiccoli: context adjustment]
Signed-off-by: Guilherme G. Piccoli <gpiccoli@canonical.com>
---
 drivers/iommu/intel-iommu.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

Comments

Kleber Sacilotto de Souza Jan. 8, 2019, 11:51 a.m. UTC | #1
On 1/2/19 8:40 PM, Guilherme G. Piccoli wrote:
> From: Joerg Roedel <jroedel@suse.de>
>
> BugLink: https://launchpad.net/bugs/1810328
>
> When booting into a kexec kernel with intel_iommu=off, and
> the previous kernel had intel_iommu=on, the IOMMU hardware
> is still enabled and gets not disabled by the new kernel.
>
> This causes the boot to fail because DMA is blocked by the
> hardware. Disable the IOMMUs when we find it enabled in the
> kexec kernel and boot with intel_iommu=off.
>
> Signed-off-by: Joerg Roedel <jroedel@suse.de>
> (backported from commit 161b28aae1651aa7ad63ec14753aa8a751154340 upstream)
> [gpiccoli: context adjustment]
> Signed-off-by: Guilherme G. Piccoli <gpiccoli@canonical.com>

This is a patch that would have been nice if someone had sent it to
-stable 4.4 :-)

Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>

> ---
>  drivers/iommu/intel-iommu.c | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
> index 49b266433f4c..03f817d118f3 100644
> --- a/drivers/iommu/intel-iommu.c
> +++ b/drivers/iommu/intel-iommu.c
> @@ -4648,6 +4648,15 @@ const struct attribute_group *intel_iommu_groups[] = {
>  	NULL,
>  };
>  
> +static void intel_disable_iommus(void)
> +{
> +	struct intel_iommu *iommu = NULL;
> +	struct dmar_drhd_unit *drhd;
> +
> +	for_each_iommu(iommu, drhd)
> +		iommu_disable_translation(iommu);
> +}
> +
>  int __init intel_iommu_init(void)
>  {
>  	int ret = -ENODEV;
> @@ -4676,8 +4685,15 @@ int __init intel_iommu_init(void)
>  		goto out_free_dmar;
>  	}
>  
> -	if (no_iommu || dmar_disabled)
> +	if (no_iommu || dmar_disabled) {
> +		/*
> +		 * Make sure the IOMMUs are switched off, even when we
> +		 * boot into a kexec kernel and the previous kernel left
> +		 * them enabled
> +		 */
> +		intel_disable_iommus();
>  		goto out_free_dmar;
> +	}
>  
>  	if (list_empty(&dmar_rmrr_units))
>  		pr_info("No RMRR found\n");
Guilherme G. Piccoli Jan. 8, 2019, 12:36 p.m. UTC | #2
On 08/01/2019 09:51, Kleber Souza wrote:
> [...]
> This is a patch that would have been nice if someone had sent it to
> -stable 4.4 :-)

Thanks for the ACK Kleber. Totally agree with you, but stable process
missed this patch so I thought in adding this at least in our kernel heheh

Cheers,


Guilherme
Stefan Bader Jan. 9, 2019, 10:38 a.m. UTC | #3
On 02.01.19 20:40, Guilherme G. Piccoli wrote:
> From: Joerg Roedel <jroedel@suse.de>
> 
> BugLink: https://launchpad.net/bugs/1810328
> 
> When booting into a kexec kernel with intel_iommu=off, and
> the previous kernel had intel_iommu=on, the IOMMU hardware
> is still enabled and gets not disabled by the new kernel.
> 
> This causes the boot to fail because DMA is blocked by the
> hardware. Disable the IOMMUs when we find it enabled in the
> kexec kernel and boot with intel_iommu=off.
> 
> Signed-off-by: Joerg Roedel <jroedel@suse.de>
> (backported from commit 161b28aae1651aa7ad63ec14753aa8a751154340 upstream)
> [gpiccoli: context adjustment]
> Signed-off-by: Guilherme G. Piccoli <gpiccoli@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
> ---
>  drivers/iommu/intel-iommu.c | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
> index 49b266433f4c..03f817d118f3 100644
> --- a/drivers/iommu/intel-iommu.c
> +++ b/drivers/iommu/intel-iommu.c
> @@ -4648,6 +4648,15 @@ const struct attribute_group *intel_iommu_groups[] = {
>  	NULL,
>  };
>  
> +static void intel_disable_iommus(void)
> +{
> +	struct intel_iommu *iommu = NULL;
> +	struct dmar_drhd_unit *drhd;
> +
> +	for_each_iommu(iommu, drhd)
> +		iommu_disable_translation(iommu);
> +}
> +
>  int __init intel_iommu_init(void)
>  {
>  	int ret = -ENODEV;
> @@ -4676,8 +4685,15 @@ int __init intel_iommu_init(void)
>  		goto out_free_dmar;
>  	}
>  
> -	if (no_iommu || dmar_disabled)
> +	if (no_iommu || dmar_disabled) {
> +		/*
> +		 * Make sure the IOMMUs are switched off, even when we
> +		 * boot into a kexec kernel and the previous kernel left
> +		 * them enabled
> +		 */
> +		intel_disable_iommus();
>  		goto out_free_dmar;
> +	}
>  
>  	if (list_empty(&dmar_rmrr_units))
>  		pr_info("No RMRR found\n");
>
diff mbox series

Patch

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 49b266433f4c..03f817d118f3 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -4648,6 +4648,15 @@  const struct attribute_group *intel_iommu_groups[] = {
 	NULL,
 };
 
+static void intel_disable_iommus(void)
+{
+	struct intel_iommu *iommu = NULL;
+	struct dmar_drhd_unit *drhd;
+
+	for_each_iommu(iommu, drhd)
+		iommu_disable_translation(iommu);
+}
+
 int __init intel_iommu_init(void)
 {
 	int ret = -ENODEV;
@@ -4676,8 +4685,15 @@  int __init intel_iommu_init(void)
 		goto out_free_dmar;
 	}
 
-	if (no_iommu || dmar_disabled)
+	if (no_iommu || dmar_disabled) {
+		/*
+		 * Make sure the IOMMUs are switched off, even when we
+		 * boot into a kexec kernel and the previous kernel left
+		 * them enabled
+		 */
+		intel_disable_iommus();
 		goto out_free_dmar;
+	}
 
 	if (list_empty(&dmar_rmrr_units))
 		pr_info("No RMRR found\n");