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 |
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");
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
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 --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");