diff mbox series

[Unstable,SRU,Disco] iommu/arm-smmu-v3: Don't disable SMMU inkdump kernel

Message ID 20190513182823.11804-1-dann.frazier@canonical.com
State New
Headers show
Series [Unstable,SRU,Disco] iommu/arm-smmu-v3: Don't disable SMMU inkdump kernel | expand

Commit Message

dann frazier May 13, 2019, 6:28 p.m. UTC
From: Will Deacon <will.deacon@arm.com>

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

Disabling the SMMU when probing from within a kdump kernel so that all
incoming transactions are terminated can prevent the core of the crashed
kernel from being transferred off the machine if all I/O devices are
behind the SMMU.

Instead, continue to probe the SMMU after it is disabled so that we can
reinitialise it entirely and re-attach the DMA masters as they are reset.
Since the kdump kernel may not have drivers for all of the active DMA
masters, we suppress fault reporting to avoid spamming the console and
swamping the IRQ threads.

Reported-by: "Leizhen (ThunderTown)" <thunder.leizhen@huawei.com>
Tested-by: "Leizhen (ThunderTown)" <thunder.leizhen@huawei.com>
Tested-by: Bhupesh Sharma <bhsharma@redhat.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
(cherry picked from commit 3f54c447df34ff9efac7809a4a80fd3208efc619)
Signed-off-by: dann frazier <dann.frazier@canonical.com>
---
 drivers/iommu/arm-smmu-v3.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

Comments

Stefan Bader May 29, 2019, 2:11 p.m. UTC | #1
On 13.05.19 20:28, dann frazier wrote:
> From: Will Deacon <will.deacon@arm.com>
> 
> BugLink: https://bugs.launchpad.net/bugs/1828868
> 
> Disabling the SMMU when probing from within a kdump kernel so that all
> incoming transactions are terminated can prevent the core of the crashed
> kernel from being transferred off the machine if all I/O devices are
> behind the SMMU.
> 
> Instead, continue to probe the SMMU after it is disabled so that we can
> reinitialise it entirely and re-attach the DMA masters as they are reset.
> Since the kdump kernel may not have drivers for all of the active DMA
> masters, we suppress fault reporting to avoid spamming the console and
> swamping the IRQ threads.
> 
> Reported-by: "Leizhen (ThunderTown)" <thunder.leizhen@huawei.com>
> Tested-by: "Leizhen (ThunderTown)" <thunder.leizhen@huawei.com>
> Tested-by: Bhupesh Sharma <bhsharma@redhat.com>
> Signed-off-by: Will Deacon <will.deacon@arm.com>
> (cherry picked from commit 3f54c447df34ff9efac7809a4a80fd3208efc619)
> Signed-off-by: dann frazier <dann.frazier@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
> ---
>  drivers/iommu/arm-smmu-v3.c | 10 ++++------
>  1 file changed, 4 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
> index 0d284029dc735..e6baf509bc07d 100644
> --- a/drivers/iommu/arm-smmu-v3.c
> +++ b/drivers/iommu/arm-smmu-v3.c
> @@ -2455,13 +2455,9 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
>  	/* Clear CR0 and sync (disables SMMU and queue processing) */
>  	reg = readl_relaxed(smmu->base + ARM_SMMU_CR0);
>  	if (reg & CR0_SMMUEN) {
> -		if (is_kdump_kernel()) {
> -			arm_smmu_update_gbpa(smmu, GBPA_ABORT, 0);
> -			arm_smmu_device_disable(smmu);
> -			return -EBUSY;
> -		}
> -
>  		dev_warn(smmu->dev, "SMMU currently enabled! Resetting...\n");
> +		WARN_ON(is_kdump_kernel() && !disable_bypass);
> +		arm_smmu_update_gbpa(smmu, GBPA_ABORT, 0);
>  	}
>  
>  	ret = arm_smmu_device_disable(smmu);
> @@ -2554,6 +2550,8 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
>  		return ret;
>  	}
>  
> +	if (is_kdump_kernel())
> +		enables &= ~(CR0_EVTQEN | CR0_PRIQEN);
>  
>  	/* Enable the SMMU interface, or ensure bypass */
>  	if (!bypass || disable_bypass) {
>
Seth Forshee May 29, 2019, 5:53 p.m. UTC | #2
On Mon, May 13, 2019 at 12:28:23PM -0600, dann frazier wrote:
> From: Will Deacon <will.deacon@arm.com>
> 
> BugLink: https://bugs.launchpad.net/bugs/1828868
> 
> Disabling the SMMU when probing from within a kdump kernel so that all
> incoming transactions are terminated can prevent the core of the crashed
> kernel from being transferred off the machine if all I/O devices are
> behind the SMMU.
> 
> Instead, continue to probe the SMMU after it is disabled so that we can
> reinitialise it entirely and re-attach the DMA masters as they are reset.
> Since the kdump kernel may not have drivers for all of the active DMA
> masters, we suppress fault reporting to avoid spamming the console and
> swamping the IRQ threads.
> 
> Reported-by: "Leizhen (ThunderTown)" <thunder.leizhen@huawei.com>
> Tested-by: "Leizhen (ThunderTown)" <thunder.leizhen@huawei.com>
> Tested-by: Bhupesh Sharma <bhsharma@redhat.com>
> Signed-off-by: Will Deacon <will.deacon@arm.com>
> (cherry picked from commit 3f54c447df34ff9efac7809a4a80fd3208efc619)
> Signed-off-by: dann frazier <dann.frazier@canonical.com>

Acked-by: Seth Forshee <seth.forshee@canonical.com>

This is already present in unstable/master. Thanks!
Kleber Sacilotto de Souza June 3, 2019, 2:36 p.m. UTC | #3
On 5/13/19 8:28 PM, dann frazier wrote:
> From: Will Deacon <will.deacon@arm.com>
> 
> BugLink: https://bugs.launchpad.net/bugs/1828868
> 
> Disabling the SMMU when probing from within a kdump kernel so that all
> incoming transactions are terminated can prevent the core of the crashed
> kernel from being transferred off the machine if all I/O devices are
> behind the SMMU.
> 
> Instead, continue to probe the SMMU after it is disabled so that we can
> reinitialise it entirely and re-attach the DMA masters as they are reset.
> Since the kdump kernel may not have drivers for all of the active DMA
> masters, we suppress fault reporting to avoid spamming the console and
> swamping the IRQ threads.
> 
> Reported-by: "Leizhen (ThunderTown)" <thunder.leizhen@huawei.com>
> Tested-by: "Leizhen (ThunderTown)" <thunder.leizhen@huawei.com>
> Tested-by: Bhupesh Sharma <bhsharma@redhat.com>
> Signed-off-by: Will Deacon <will.deacon@arm.com>
> (cherry picked from commit 3f54c447df34ff9efac7809a4a80fd3208efc619)
> Signed-off-by: dann frazier <dann.frazier@canonical.com>
> ---
>  drivers/iommu/arm-smmu-v3.c | 10 ++++------
>  1 file changed, 4 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
> index 0d284029dc735..e6baf509bc07d 100644
> --- a/drivers/iommu/arm-smmu-v3.c
> +++ b/drivers/iommu/arm-smmu-v3.c
> @@ -2455,13 +2455,9 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
>  	/* Clear CR0 and sync (disables SMMU and queue processing) */
>  	reg = readl_relaxed(smmu->base + ARM_SMMU_CR0);
>  	if (reg & CR0_SMMUEN) {
> -		if (is_kdump_kernel()) {
> -			arm_smmu_update_gbpa(smmu, GBPA_ABORT, 0);
> -			arm_smmu_device_disable(smmu);
> -			return -EBUSY;
> -		}
> -
>  		dev_warn(smmu->dev, "SMMU currently enabled! Resetting...\n");
> +		WARN_ON(is_kdump_kernel() && !disable_bypass);
> +		arm_smmu_update_gbpa(smmu, GBPA_ABORT, 0);
>  	}
>  
>  	ret = arm_smmu_device_disable(smmu);
> @@ -2554,6 +2550,8 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
>  		return ret;
>  	}
>  
> +	if (is_kdump_kernel())
> +		enables &= ~(CR0_EVTQEN | CR0_PRIQEN);
>  
>  	/* Enable the SMMU interface, or ensure bypass */
>  	if (!bypass || disable_bypass) {
> 

Applied to disco/master-next branch.

Thanks,
Kleber
diff mbox series

Patch

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 0d284029dc735..e6baf509bc07d 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2455,13 +2455,9 @@  static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
 	/* Clear CR0 and sync (disables SMMU and queue processing) */
 	reg = readl_relaxed(smmu->base + ARM_SMMU_CR0);
 	if (reg & CR0_SMMUEN) {
-		if (is_kdump_kernel()) {
-			arm_smmu_update_gbpa(smmu, GBPA_ABORT, 0);
-			arm_smmu_device_disable(smmu);
-			return -EBUSY;
-		}
-
 		dev_warn(smmu->dev, "SMMU currently enabled! Resetting...\n");
+		WARN_ON(is_kdump_kernel() && !disable_bypass);
+		arm_smmu_update_gbpa(smmu, GBPA_ABORT, 0);
 	}
 
 	ret = arm_smmu_device_disable(smmu);
@@ -2554,6 +2550,8 @@  static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
 		return ret;
 	}
 
+	if (is_kdump_kernel())
+		enables &= ~(CR0_EVTQEN | CR0_PRIQEN);
 
 	/* Enable the SMMU interface, or ensure bypass */
 	if (!bypass || disable_bypass) {