Commit ddfffa59 authored by Will Deacon's avatar Will Deacon Committed by Greg Kroah-Hartman

iommu/arm-smmu-v3: Don't disable SMMU in kdump kernel

[ Upstream commit 3f54c447 ]

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: default avatar"Leizhen (ThunderTown)" <thunder.leizhen@huawei.com>
Tested-by: default avatar"Leizhen (ThunderTown)" <thunder.leizhen@huawei.com>
Tested-by: default avatarBhupesh Sharma <bhsharma@redhat.com>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 6a3bde70
...@@ -2454,13 +2454,9 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass) ...@@ -2454,13 +2454,9 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
/* Clear CR0 and sync (disables SMMU and queue processing) */ /* Clear CR0 and sync (disables SMMU and queue processing) */
reg = readl_relaxed(smmu->base + ARM_SMMU_CR0); reg = readl_relaxed(smmu->base + ARM_SMMU_CR0);
if (reg & CR0_SMMUEN) { 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"); 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); ret = arm_smmu_device_disable(smmu);
...@@ -2553,6 +2549,8 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass) ...@@ -2553,6 +2549,8 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
return ret; return ret;
} }
if (is_kdump_kernel())
enables &= ~(CR0_EVTQEN | CR0_PRIQEN);
/* Enable the SMMU interface, or ensure bypass */ /* Enable the SMMU interface, or ensure bypass */
if (!bypass || disable_bypass) { if (!bypass || disable_bypass) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment