From d68d0071e1171e0e6b55d8e6768d51c34e208248 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 22 May 2019 16:49:39 +0800 Subject: [PATCH] iommu/arm-smmu-v3: Don't disable SMMU in kdump kernel mainline inclusion from mainline-v5.2-rc1 commit 3f54c447df34ff9efac7809a4a80fd3208efc619 category: bugfix bugzilla: 5452 CVE: NA ------------------------------------------------------------------------- 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)" Tested-by: "Leizhen (ThunderTown)" Tested-by: Bhupesh Sharma Signed-off-by: Will Deacon Signed-off-by: Zhen Lei Reviewed-by: Hanjun Guo Signed-off-by: Yang Yingliang --- 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 ed17f3efa81a..c2eff42f2bc1 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -3422,13 +3422,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); @@ -3538,6 +3534,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) { -- GitLab