From: Greg Kroah-Hartman Date: Mon, 13 Mar 2023 11:26:06 +0000 (+0100) Subject: 5.15-stable patches X-Git-Tag: v4.14.310~91 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c7ac739f6da4c0bc0a18a88c5736521adfd82be6;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: irqdomain-fix-mapping-creation-race.patch nfc-change-order-inside-nfc_se_io-error-path.patch --- diff --git a/queue-5.15/irqdomain-fix-mapping-creation-race.patch b/queue-5.15/irqdomain-fix-mapping-creation-race.patch new file mode 100644 index 00000000000..38b696d9caa --- /dev/null +++ b/queue-5.15/irqdomain-fix-mapping-creation-race.patch @@ -0,0 +1,179 @@ +From 601363cc08da25747feb87c55573dd54de91d66a Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 13 Feb 2023 11:42:48 +0100 +Subject: irqdomain: Fix mapping-creation race + +From: Johan Hovold + +commit 601363cc08da25747feb87c55573dd54de91d66a upstream. + +Parallel probing of devices that share interrupts (e.g. when a driver +uses asynchronous probing) can currently result in two mappings for the +same hardware interrupt to be created due to missing serialisation. + +Make sure to hold the irq_domain_mutex when creating mappings so that +looking for an existing mapping before creating a new one is done +atomically. + +Fixes: 765230b5f084 ("driver-core: add asynchronous probing support for drivers") +Fixes: b62b2cf5759b ("irqdomain: Fix handling of type settings for existing mappings") +Link: https://lore.kernel.org/r/YuJXMHoT4ijUxnRb@hovoldconsulting.com +Cc: stable@vger.kernel.org # 4.8 +Cc: Dmitry Torokhov +Cc: Jon Hunter +Tested-by: Hsin-Yi Wang +Tested-by: Mark-PK Tsai +Signed-off-by: Johan Hovold +Signed-off-by: Marc Zyngier +Link: https://lore.kernel.org/r/20230213104302.17307-7-johan+linaro@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + kernel/irq/irqdomain.c | 64 +++++++++++++++++++++++++++++++++++-------------- + 1 file changed, 46 insertions(+), 18 deletions(-) + +--- a/kernel/irq/irqdomain.c ++++ b/kernel/irq/irqdomain.c +@@ -25,6 +25,9 @@ static DEFINE_MUTEX(irq_domain_mutex); + + static struct irq_domain *irq_default_domain; + ++static int irq_domain_alloc_irqs_locked(struct irq_domain *domain, int irq_base, ++ unsigned int nr_irqs, int node, void *arg, ++ bool realloc, const struct irq_affinity_desc *affinity); + static void irq_domain_check_hierarchy(struct irq_domain *domain); + + struct irqchip_fwid { +@@ -703,9 +706,9 @@ unsigned int irq_create_direct_mapping(s + EXPORT_SYMBOL_GPL(irq_create_direct_mapping); + #endif + +-static unsigned int __irq_create_mapping_affinity(struct irq_domain *domain, +- irq_hw_number_t hwirq, +- const struct irq_affinity_desc *affinity) ++static unsigned int irq_create_mapping_affinity_locked(struct irq_domain *domain, ++ irq_hw_number_t hwirq, ++ const struct irq_affinity_desc *affinity) + { + struct device_node *of_node = irq_domain_get_of_node(domain); + int virq; +@@ -720,7 +723,7 @@ static unsigned int __irq_create_mapping + return 0; + } + +- if (irq_domain_associate(domain, virq, hwirq)) { ++ if (irq_domain_associate_locked(domain, virq, hwirq)) { + irq_free_desc(virq); + return 0; + } +@@ -756,14 +759,20 @@ unsigned int irq_create_mapping_affinity + return 0; + } + ++ mutex_lock(&irq_domain_mutex); ++ + /* Check if mapping already exists */ + virq = irq_find_mapping(domain, hwirq); + if (virq) { + pr_debug("existing mapping on virq %d\n", virq); +- return virq; ++ goto out; + } + +- return __irq_create_mapping_affinity(domain, hwirq, affinity); ++ virq = irq_create_mapping_affinity_locked(domain, hwirq, affinity); ++out: ++ mutex_unlock(&irq_domain_mutex); ++ ++ return virq; + } + EXPORT_SYMBOL_GPL(irq_create_mapping_affinity); + +@@ -830,6 +839,8 @@ unsigned int irq_create_fwspec_mapping(s + if (WARN_ON(type & ~IRQ_TYPE_SENSE_MASK)) + type &= IRQ_TYPE_SENSE_MASK; + ++ mutex_lock(&irq_domain_mutex); ++ + /* + * If we've already configured this interrupt, + * don't do it again, or hell will break loose. +@@ -842,7 +853,7 @@ unsigned int irq_create_fwspec_mapping(s + * interrupt number. + */ + if (type == IRQ_TYPE_NONE || type == irq_get_trigger_type(virq)) +- return virq; ++ goto out; + + /* + * If the trigger type has not been set yet, then set +@@ -850,35 +861,45 @@ unsigned int irq_create_fwspec_mapping(s + */ + if (irq_get_trigger_type(virq) == IRQ_TYPE_NONE) { + irq_data = irq_get_irq_data(virq); +- if (!irq_data) +- return 0; ++ if (!irq_data) { ++ virq = 0; ++ goto out; ++ } + + irqd_set_trigger_type(irq_data, type); +- return virq; ++ goto out; + } + + pr_warn("type mismatch, failed to map hwirq-%lu for %s!\n", + hwirq, of_node_full_name(to_of_node(fwspec->fwnode))); +- return 0; ++ virq = 0; ++ goto out; + } + + if (irq_domain_is_hierarchy(domain)) { +- virq = irq_domain_alloc_irqs(domain, 1, NUMA_NO_NODE, fwspec); +- if (virq <= 0) +- return 0; ++ virq = irq_domain_alloc_irqs_locked(domain, -1, 1, NUMA_NO_NODE, ++ fwspec, false, NULL); ++ if (virq <= 0) { ++ virq = 0; ++ goto out; ++ } + } else { + /* Create mapping */ +- virq = __irq_create_mapping_affinity(domain, hwirq, NULL); ++ virq = irq_create_mapping_affinity_locked(domain, hwirq, NULL); + if (!virq) +- return virq; ++ goto out; + } + + irq_data = irq_get_irq_data(virq); +- if (WARN_ON(!irq_data)) +- return 0; ++ if (WARN_ON(!irq_data)) { ++ virq = 0; ++ goto out; ++ } + + /* Store trigger type */ + irqd_set_trigger_type(irq_data, type); ++out: ++ mutex_unlock(&irq_domain_mutex); + + return virq; + } +@@ -1902,6 +1923,13 @@ void irq_domain_set_info(struct irq_doma + irq_set_handler_data(virq, handler_data); + } + ++static int irq_domain_alloc_irqs_locked(struct irq_domain *domain, int irq_base, ++ unsigned int nr_irqs, int node, void *arg, ++ bool realloc, const struct irq_affinity_desc *affinity) ++{ ++ return -EINVAL; ++} ++ + static void irq_domain_check_hierarchy(struct irq_domain *domain) + { + } diff --git a/queue-5.15/nfc-change-order-inside-nfc_se_io-error-path.patch b/queue-5.15/nfc-change-order-inside-nfc_se_io-error-path.patch new file mode 100644 index 00000000000..80f3ee02af0 --- /dev/null +++ b/queue-5.15/nfc-change-order-inside-nfc_se_io-error-path.patch @@ -0,0 +1,38 @@ +From 7d834b4d1ab66c48e8c0810fdeadaabb80fa2c81 Mon Sep 17 00:00:00 2001 +From: Fedor Pchelkin +Date: Tue, 7 Mar 2023 00:26:50 +0300 +Subject: nfc: change order inside nfc_se_io error path + +From: Fedor Pchelkin + +commit 7d834b4d1ab66c48e8c0810fdeadaabb80fa2c81 upstream. + +cb_context should be freed on the error path in nfc_se_io as stated by +commit 25ff6f8a5a3b ("nfc: fix memory leak of se_io context in +nfc_genl_se_io"). + +Make the error path in nfc_se_io unwind everything in reverse order, i.e. +free the cb_context after unlocking the device. + +Suggested-by: Krzysztof Kozlowski +Signed-off-by: Fedor Pchelkin +Reviewed-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20230306212650.230322-1-pchelkin@ispras.ru +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/nfc/netlink.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/nfc/netlink.c ++++ b/net/nfc/netlink.c +@@ -1446,8 +1446,8 @@ static int nfc_se_io(struct nfc_dev *dev + return rc; + + error: +- kfree(cb_context); + device_unlock(&dev->dev); ++ kfree(cb_context); + return rc; + } + diff --git a/queue-5.15/series b/queue-5.15/series index 4b5dd7e3917..8f08b75e6e2 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -12,3 +12,5 @@ ext4-fix-another-off-by-one-fsmap-error-on-1k-block-filesystems.patch ext4-move-where-set-the-may_inline_data-flag-is-set.patch ext4-fix-warning-in-ext4_update_inline_data.patch ext4-zero-i_disksize-when-initializing-the-bootloader-inode.patch +nfc-change-order-inside-nfc_se_io-error-path.patch +irqdomain-fix-mapping-creation-race.patch