Received: by 2002:a05:6358:11c7:b0:104:8066:f915 with SMTP id i7csp6035860rwl; Wed, 22 Mar 2023 05:51:33 -0700 (PDT) X-Google-Smtp-Source: AKy350bczlb1UaWhsbyx+UbkVgeZXwGbVNTa7BmdJ5ouCldun4W/pRS6zuf6mElYjF5beGbJwxdJ X-Received: by 2002:a17:902:e5c9:b0:19a:7217:32a9 with SMTP id u9-20020a170902e5c900b0019a721732a9mr2323450plf.26.1679489493701; Wed, 22 Mar 2023 05:51:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679489493; cv=none; d=google.com; s=arc-20160816; b=BbCaRR19iAaFkH2fHh5r+olbX6rOwksIZPTchYT/AiSBZBrFQlOX7MDq89iBAMtYjU uQQuwkQ8WsDlnQ+/gKRtIjIjvKSZzkT9iCDPYBTj87rBAh4OR/OJw0UJ4lYXLbJfo44b UzfWsPG15Dcekq5PYeor94WgqxRORh7XFxxsX6Iwk4GdFPfnsfY4e+oE1wWoScj90Z4b 2kzXVRzWB4Lfg1rMoW+E9Q4tw/+1GRt6Z4L6oX1lObxPxQvQWUHn5WRbQ9GuVTWOqUB7 vqHrqtQFIWaXTEVt/I+OWJfQIqPmL+xIjehNyUZQQT6RF9AYOtd573/pb4hGnA9dO8or 6Udg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=RtlyoNDumdqdrT5xCZJJmPiYA26C5IwVsi00DfMAgpU=; b=mCX4Toov+6ry8h5nJAK3gvpoyN+iSOa0VjtW+yJ9iXTQioy2DURNrM95h04OiioOE/ tQZf1ERlrstSo1tZc7krG0w976VHltA41Ki6drzsqgRtdr6NJjSJ7dvDlSIChQygwXL6 95NdNGq3aqPDX9rZvQ1ouH1R9zx6X3Cp//43EbSfHcPopaKQdAhuZAhRQZ+lEhPPa7RE OMPspwdOK5kfCVV/Tgt2ogQMravOloTexVF3X+7VEWJjf6g0idpx/igmp5GMhjfkAzbQ ErbJNKwEDFG4gKn8z1LsGShEl4CcUMWR5J2N0UofPix6FaBuZ41napSpSIUwM/hEp8np 6yOg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@mediatek.com header.s=dk header.b=MRSgzKhz; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=mediatek.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b11-20020a170902b60b00b001a1f831341asi399062pls.458.2023.03.22.05.51.22; Wed, 22 Mar 2023 05:51:33 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@mediatek.com header.s=dk header.b=MRSgzKhz; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=mediatek.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230397AbjCVMqH (ORCPT + 99 others); Wed, 22 Mar 2023 08:46:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57906 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230384AbjCVMqE (ORCPT ); Wed, 22 Mar 2023 08:46:04 -0400 Received: from mailgw02.mediatek.com (unknown [210.61.82.184]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EDA743B221; Wed, 22 Mar 2023 05:46:01 -0700 (PDT) X-UUID: 7d5277e2c8af11edb6b9f13eb10bd0fe-20230322 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=RtlyoNDumdqdrT5xCZJJmPiYA26C5IwVsi00DfMAgpU=; b=MRSgzKhzlx8ebdbfs9nk4vNLc888IUTSHoRxBs/h8Q+TJcqsJN/fEQF1xcljrlvTY/SOa9ygKjoYFaKPkoRNrtjhoIrPhBsxKTY4TribcNkxfojwlIN33KuTprG5iJacG+Wud74l6Q+Z+RedO7kCpVXnet/C0XYSbuLTS72nXeI=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.22,REQID:26fcac05-bc6d-4d79-9807-94cb12049e1b,IP:0,U RL:0,TC:0,Content:-5,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTION :release,TS:-5 X-CID-META: VersionHash:120426c,CLOUDID:5b032829-564d-42d9-9875-7c868ee415ec,B ulkID:nil,BulkQuantity:0,Recheck:0,SF:102,TC:nil,Content:0,EDM:-3,IP:nil,U RL:1,File:nil,Bulk:nil,QS:nil,BEC:nil,COL:0,OSI:0,OSA:0,AV:0 X-CID-BVR: 0,NGT X-CID-BAS: 0,NGT,0,_ X-UUID: 7d5277e2c8af11edb6b9f13eb10bd0fe-20230322 Received: from mtkmbs11n2.mediatek.inc [(172.21.101.187)] by mailgw02.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 808491197; Wed, 22 Mar 2023 20:45:56 +0800 Received: from mtkmbs13n1.mediatek.inc (172.21.101.193) by mtkmbs13n2.mediatek.inc (172.21.101.108) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.25; Wed, 22 Mar 2023 20:45:55 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkmbs13n1.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.1118.25 via Frontend Transport; Wed, 22 Mar 2023 20:45:55 +0800 From: Mark-PK Tsai To: Marc Zyngier , Thomas Gleixner , Matthias Brugger CC: Johan Hovold , , Dmitry Torokhov , Jon Hunter , Sasha Levin , Mark-PK Tsai , , , Subject: [PATCH 5.4 3/3] irqdomain: Fix mapping-creation race Date: Wed, 22 Mar 2023 20:45:50 +0800 Message-ID: <20230322124550.29812-3-mark-pk.tsai@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20230322124550.29812-1-mark-pk.tsai@mediatek.com> References: <20230322124550.29812-1-mark-pk.tsai@mediatek.com> MIME-Version: 1.0 Content-Type: text/plain X-MTK: N X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,SPF_PASS, UNPARSEABLE_RELAY,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Johan Hovold [ Upstream commit 601363cc08da25747feb87c55573dd54de91d66a ] 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: Sasha Levin Signed-off-by: Mark-PK Tsai --- kernel/irq/irqdomain.c | 64 ++++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 1eb34eaeaa94..a5f1dd7b6dc3 100644 --- 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 { @@ -672,9 +675,9 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain) } EXPORT_SYMBOL_GPL(irq_create_direct_mapping); -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; @@ -689,7 +692,7 @@ static unsigned int __irq_create_mapping_affinity(struct irq_domain *domain, return 0; } - if (irq_domain_associate(domain, virq, hwirq)) { + if (irq_domain_associate_locked(domain, virq, hwirq)) { irq_free_desc(virq); return 0; } @@ -725,14 +728,20 @@ unsigned int irq_create_mapping_affinity(struct irq_domain *domain, 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); @@ -834,6 +843,8 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec) 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. @@ -846,7 +857,7 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec) * 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 @@ -854,35 +865,45 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec) */ 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; } @@ -1788,6 +1809,13 @@ void irq_domain_set_info(struct irq_domain *domain, unsigned int virq, 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) { } -- 2.18.0