[PATCH v5 3/6] iommu/arm-smmu-v3: Suppress EVTQ/PRIQ events in kdump kernel
Nicolin Chen
nicolinc at nvidia.com
Sun May 10 14:23:02 PDT 2026
In kdump cases, the crashed kernel's CDs and page tables can be corrupted,
which could trigger event spamming. Also, we cannot serve page requests.
Skip the IRQ setup for EVTQ/PRIQ in arm_smmu_setup_irqs(), and guard the
thread functions against being entered via a combined-IRQ delivery while
the queue is disabled.
Fixes: b63b3439b856 ("iommu/arm-smmu-v3: Abort all transactions if SMMU is enabled in kdump kernel")
Cc: stable at vger.kernel.org # v6.12+
Reviewed-by: Kevin Tian <kevin.tian at intel.com>
Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 23 +++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 579c8af82d6b6..ebb0826d74541 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2364,6 +2364,14 @@ static irqreturn_t arm_smmu_evtq_thread(int irq, void *dev)
static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL,
DEFAULT_RATELIMIT_BURST);
+ /*
+ * A combined IRQ might call into this function with the queue disabled.
+ * E.g. kdump, where stale HW PROD vs SW CONS would drive a bogus drain
+ * and a CONS write to a disabled queue.
+ */
+ if (!(readl_relaxed(smmu->base + ARM_SMMU_CR0) & CR0_EVTQEN))
+ return IRQ_NONE;
+
do {
while (!queue_remove_raw(q, evt)) {
arm_smmu_decode_event(smmu, evt, &event);
@@ -2432,6 +2440,14 @@ static irqreturn_t arm_smmu_priq_thread(int irq, void *dev)
struct arm_smmu_ll_queue *llq = &q->llq;
u64 evt[PRIQ_ENT_DWORDS];
+ /*
+ * A combined IRQ might call into this function with the queue disabled.
+ * E.g. kdump, where stale HW PROD vs SW CONS would drive a bogus drain
+ * and a CONS write to a disabled queue.
+ */
+ if (!(readl_relaxed(smmu->base + ARM_SMMU_CR0) & CR0_PRIQEN))
+ return IRQ_NONE;
+
do {
while (!queue_remove_raw(q, evt))
arm_smmu_handle_ppr(smmu, evt);
@@ -5056,7 +5072,10 @@ static void arm_smmu_setup_unique_irqs(struct arm_smmu_device *smmu)
static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
{
int ret, irq;
- u32 irqen_flags = IRQ_CTRL_EVTQ_IRQEN | IRQ_CTRL_GERROR_IRQEN;
+ u32 irqen_flags = IRQ_CTRL_GERROR_IRQEN;
+
+ if (!is_kdump_kernel())
+ irqen_flags |= IRQ_CTRL_EVTQ_IRQEN;
/* Disable IRQs first */
ret = arm_smmu_write_reg_sync(smmu, 0, ARM_SMMU_IRQ_CTRL,
@@ -5082,7 +5101,7 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
} else
arm_smmu_setup_unique_irqs(smmu);
- if (smmu->features & ARM_SMMU_FEAT_PRI)
+ if (!is_kdump_kernel() && (smmu->features & ARM_SMMU_FEAT_PRI))
irqen_flags |= IRQ_CTRL_PRIQ_IRQEN;
/* Enable interrupt generation on the SMMU */
--
2.43.0
More information about the linux-arm-kernel
mailing list