summaryrefslogtreecommitdiffstats
path: root/kernel/irq
diff options
context:
space:
mode:
authorJohan Hovold <johan+linaro@kernel.org>2023-02-13 11:42:44 +0100
committerMarc Zyngier <maz@kernel.org>2023-02-13 19:31:24 +0000
commit3f883c38f5628f46b30bccf090faec054088e262 (patch)
treef9eaac516f5c7c2829d575db35f59d1fcf4fbf67 /kernel/irq
parentb06730a571a9ff1ba5bd6b20bf9e50e5a12f1ec6 (diff)
downloadlinux-3f883c38f5628f46b30bccf090faec054088e262.tar.gz
linux-3f883c38f5628f46b30bccf090faec054088e262.tar.bz2
linux-3f883c38f5628f46b30bccf090faec054088e262.zip
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
Diffstat (limited to 'kernel/irq')
-rw-r--r--kernel/irq/irqdomain.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 6661de18550e..f77549a2a178 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,