| From 6ce3e98184b625d2870991880bf9586ded7ea7f9 Mon Sep 17 00:00:00 2001 |
| From: Herve Codina <herve.codina@bootlin.com> |
| Date: Fri, 14 Jun 2024 19:32:04 +0200 |
| Subject: irqdomain: Fixed unbalanced fwnode get and put |
| |
| From: Herve Codina <herve.codina@bootlin.com> |
| |
| commit 6ce3e98184b625d2870991880bf9586ded7ea7f9 upstream. |
| |
| fwnode_handle_get(fwnode) is called when a domain is created with fwnode |
| passed as a function parameter. fwnode_handle_put(domain->fwnode) is called |
| when the domain is destroyed but during the creation a path exists that |
| does not set domain->fwnode. |
| |
| If this path is taken, the fwnode get will never be put. |
| |
| To avoid the unbalanced get and put, set domain->fwnode unconditionally. |
| |
| Fixes: d59f6617eef0 ("genirq: Allow fwnode to carry name information only") |
| Signed-off-by: Herve Codina <herve.codina@bootlin.com> |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Cc: stable@vger.kernel.org |
| Link: https://lore.kernel.org/r/20240614173232.1184015-4-herve.codina@bootlin.com |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| kernel/irq/irqdomain.c | 7 ++----- |
| 1 file changed, 2 insertions(+), 5 deletions(-) |
| |
| --- a/kernel/irq/irqdomain.c |
| +++ b/kernel/irq/irqdomain.c |
| @@ -155,7 +155,6 @@ static struct irq_domain *__irq_domain_c |
| switch (fwid->type) { |
| case IRQCHIP_FWNODE_NAMED: |
| case IRQCHIP_FWNODE_NAMED_ID: |
| - domain->fwnode = fwnode; |
| domain->name = kstrdup(fwid->name, GFP_KERNEL); |
| if (!domain->name) { |
| kfree(domain); |
| @@ -164,7 +163,6 @@ static struct irq_domain *__irq_domain_c |
| domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED; |
| break; |
| default: |
| - domain->fwnode = fwnode; |
| domain->name = fwid->name; |
| break; |
| } |
| @@ -184,7 +182,6 @@ static struct irq_domain *__irq_domain_c |
| } |
| |
| domain->name = strreplace(name, '/', ':'); |
| - domain->fwnode = fwnode; |
| domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED; |
| } |
| |
| @@ -200,8 +197,8 @@ static struct irq_domain *__irq_domain_c |
| domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED; |
| } |
| |
| - fwnode_handle_get(fwnode); |
| - fwnode_dev_initialized(fwnode, true); |
| + domain->fwnode = fwnode_handle_get(fwnode); |
| + fwnode_dev_initialized(domain->fwnode, true); |
| |
| /* Fill structure */ |
| INIT_RADIX_TREE(&domain->revmap_tree, GFP_KERNEL); |