[irqchip:,irq/irqchip-next] irqdomain: Fix disassociation race

Message ID 167631724735.4906.17602457971577144696.tip-bot2@tip-bot2
State New
Headers
Series [irqchip:,irq/irqchip-next] irqdomain: Fix disassociation race |

Commit Message

tip-bot2 for Thomas Gleixner Feb. 13, 2023, 7:40 p.m. UTC
  The following commit has been merged into the irq/irqchip-next branch of irqchip:

Commit-ID:     3f883c38f5628f46b30bccf090faec054088e262
Gitweb:        https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms/3f883c38f5628f46b30bccf090faec054088e262
Author:        Johan Hovold <johan+linaro@kernel.org>
AuthorDate:    Mon, 13 Feb 2023 11:42:44 +01:00
Committer:     Marc Zyngier <maz@kernel.org>
CommitterDate: Mon, 13 Feb 2023 19:31:24 

irqdomain: Fix disassociation race

The global irq_domain_mutex is held when mapping interrupts from
non-hierarchical domains but currently not when disposing them.

This specifically means that updates of the domain mapcount is racy
(currently only used for statistics in debugfs).

Make sure to hold the global irq_domain_mutex also when disposing
mappings from non-hierarchical domains.

Fixes: 9dc6be3d4193 ("genirq/irqdomain: Add map counter")
Cc: stable@vger.kernel.org      # 4.13
Tested-by: Hsin-Yi Wang <hsinyi@chromium.org>
Tested-by: Mark-PK Tsai <mark-pk.tsai@mediatek.com>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20230213104302.17307-3-johan+linaro@kernel.org
---
 kernel/irq/irqdomain.c | 5 +++++
 1 file changed, 5 insertions(+)
  

Patch

diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 6661de1..f77549a 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -538,6 +538,9 @@  static void irq_domain_disassociate(struct irq_domain *domain, unsigned int irq)
 		return;
 
 	hwirq = irq_data->hwirq;
+
+	mutex_lock(&irq_domain_mutex);
+
 	irq_set_status_flags(irq, IRQ_NOREQUEST);
 
 	/* remove chip and handler */
@@ -557,6 +560,8 @@  static void irq_domain_disassociate(struct irq_domain *domain, unsigned int irq)
 
 	/* Clear reverse map for this hwirq */
 	irq_domain_clear_mapping(domain, hwirq);
+
+	mutex_unlock(&irq_domain_mutex);
 }
 
 static int irq_domain_associate_locked(struct irq_domain *domain, unsigned int virq,