summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBhargav Joshi <j.bhargav.u@gmail.com>2026-06-20 15:09:16 +0300
committerThomas Gleixner <tglx@kernel.org>2026-06-21 15:59:20 +0300
commit043db005a8d6932dc7d217c86307e9af0bc10ddc (patch)
tree51836b87fbe5ce2d3ae799ad7d0e72f3e30dff69
parenta552c81ff4a16738ca5a44a177d552eb38d552ce (diff)
downloadlinux-043db005a8d6932dc7d217c86307e9af0bc10ddc.tar.xz
irqchip/crossbar: Use correct index in crossbar_domain_free()
crossbar_domain_free() resets the domain data and then uses the nulled out irq_data->hwirq member as index to reset the irq_map[] entry and to write the relevant crossbar register with a safe entry. That means it never frees the correct index and keeps the crossbar register connection to the source interrupt active. If it would not reset the domain data, then this would be even worse as irq_data->hwirq holds the source interrupt number, but both the map and register index need the corresponding GIC SPI number and not the source interrupt number. This might even result in an out of bounds access as the source interrupt number can be higher than the maximal index space. Fix this by using the GIC SPI index from the parent domain's irq_data. Fixes: 783d31863fb82 ("irqchip: crossbar: Convert dra7 crossbar to stacked domains") Signed-off-by: Bhargav Joshi <j.bhargav.u@gmail.com> Signed-off-by: Thomas Gleixner <tglx@kernel.org> Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260620-irq-crossbar-fix-v2-1-b8e8499f468a@gmail.com
-rw-r--r--drivers/irqchip/irq-crossbar.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c
index cd1134101ace..4e19e9d8a41d 100644
--- a/drivers/irqchip/irq-crossbar.c
+++ b/drivers/irqchip/irq-crossbar.c
@@ -158,9 +158,14 @@ static void crossbar_domain_free(struct irq_domain *domain, unsigned int virq,
for (i = 0; i < nr_irqs; i++) {
struct irq_data *d = irq_domain_get_irq_data(domain, virq + i);
+ /*
+ * irq_map[] is indexed by GIC SPI number. The parent domain's
+ * hwirq contains the GIC interrupt number (GIC SPI +
+ * GIC_IRQ_START).
+ */
+ cb->irq_map[d->parent_data->hwirq - GIC_IRQ_START] = IRQ_FREE;
+ cb->write(d->parent_data->hwirq - GIC_IRQ_START, cb->safe_map);
irq_domain_reset_irq_data(d);
- cb->irq_map[d->hwirq] = IRQ_FREE;
- cb->write(d->hwirq, cb->safe_map);
}
raw_spin_unlock(&cb->lock);
}