aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2019-04-23 06:59:36 -0400
committerWill Deacon <will.deacon@arm.com>2019-04-23 07:23:15 -0400
commit3f54c447df34ff9efac7809a4a80fd3208efc619 (patch)
tree451b72a5be9c0ddc96d6de375709e7ae2f88e616 /drivers
parentb2fc9b4b7ff4e6d237b0118e98573c9153363ecd (diff)
iommu/arm-smmu-v3: Don't disable SMMU in kdump kernel
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/iommu/arm-smmu-v3.c10
1 files changed, 4 insertions, 6 deletions
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 99b83fda11e4..4d5a694f02c2 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2649,13 +2649,9 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
2649 /* Clear CR0 and sync (disables SMMU and queue processing) */ 2649 /* Clear CR0 and sync (disables SMMU and queue processing) */
2650 reg = readl_relaxed(smmu->base + ARM_SMMU_CR0); 2650 reg = readl_relaxed(smmu->base + ARM_SMMU_CR0);
2651 if (reg & CR0_SMMUEN) { 2651 if (reg & CR0_SMMUEN) {
2652 if (is_kdump_kernel()) {
2653 arm_smmu_update_gbpa(smmu, GBPA_ABORT, 0);
2654 arm_smmu_device_disable(smmu);
2655 return -EBUSY;
2656 }
2657
2658 dev_warn(smmu->dev, "SMMU currently enabled! Resetting...\n"); 2652 dev_warn(smmu->dev, "SMMU currently enabled! Resetting...\n");
2653 WARN_ON(is_kdump_kernel() && !disable_bypass);
2654 arm_smmu_update_gbpa(smmu, GBPA_ABORT, 0);
2659 } 2655 }
2660 2656
2661 ret = arm_smmu_device_disable(smmu); 2657 ret = arm_smmu_device_disable(smmu);
@@ -2758,6 +2754,8 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
2758 return ret; 2754 return ret;
2759 } 2755 }
2760 2756
2757 if (is_kdump_kernel())
2758 enables &= ~(CR0_EVTQEN | CR0_PRIQEN);
2761 2759
2762 /* Enable the SMMU interface, or ensure bypass */ 2760 /* Enable the SMMU interface, or ensure bypass */
2763 if (!bypass || disable_bypass) { 2761 if (!bypass || disable_bypass) {