From nobody Thu Sep 11 16:05:28 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 90415C636D4 for ; Fri, 17 Feb 2023 09:56:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230195AbjBQJ4T (ORCPT ); Fri, 17 Feb 2023 04:56:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48982 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230004AbjBQJ4N (ORCPT ); Fri, 17 Feb 2023 04:56:13 -0500 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 371425F82B for ; Fri, 17 Feb 2023 01:56:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1676627773; x=1708163773; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=soshgH1no5hycuBrP/dpzD8rbmx7eoXwNiXBGFJYNPk=; b=GsHYdIRbjYiVUumDzC3kI9t05iLXB+kWd30OPADqvqsc8LtppruAKYMW EvRVICFvW9mBmks6tKTCOSM25oqoVQHqor4JJL084gH4POm0wBRT4zknD FFuT0lJGttVKu4Md3WDbvs8OppX/77gz5PU5ANBh558yAfcuzXnyzA6ip mWqMatvOdxBKKyLWVMyZf/b2Nzg3JHlSexNSCWH/v1ClaqKKhT+bmRt9V Q35OI30KLBhNSecpZFmTGa9q4v6BYx2u1/WC94djAtLnBwXeeDDXSCHJ/ 5oeWHMI+Lo9MI3sjVt65xw+tmngOGND6CjUa267hOiuexPqe7z1jthGAi A==; X-IronPort-AV: E=McAfee;i="6500,9779,10623"; a="331955179" X-IronPort-AV: E=Sophos;i="5.97,304,1669104000"; d="scan'208";a="331955179" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Feb 2023 01:56:10 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10623"; a="999391208" X-IronPort-AV: E=Sophos;i="5.97,304,1669104000"; d="scan'208";a="999391208" Received: from allen-box.sh.intel.com ([10.239.159.48]) by fmsmga005.fm.intel.com with ESMTP; 17 Feb 2023 01:56:08 -0800 From: Lu Baolu To: iommu@lists.linux.dev Cc: Joerg Roedel , Jason Gunthorpe , Christoph Hellwig , Kevin Tian , Will Deacon , Robin Murphy , linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v2 1/6] ARM/dma-mapping: Remove iommu_detach_device() Date: Fri, 17 Feb 2023 17:47:31 +0800 Message-Id: <20230217094736.159005-2-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230217094736.159005-1-baolu.lu@linux.intel.com> References: <20230217094736.159005-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" iommu_detach_device() attaches the default domain to the device, or if default domain is not supported by the IOMMU driver, it calls its set_platform_dma_ops callback. If the default domain is supported or the IOMMU driver is not iommu-dma aware, iommu_detach_device() is actually a noop. The 64-bit ARM drivers always support default domain and iommu-dma is even not enabled for 32-bit ARM. This turns out that iommu_detach_device() is always a noop in arm_iommu_detach_device(). Remove it to avoid dead code. The bonus is that it also removes a obstacle of arm_iommu_detach_device() re-entering the iommu core during release_device. With this removed, the iommu core code could be simplified a lot. Signed-off-by: Lu Baolu --- arch/arm/mm/dma-mapping.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 8bc01071474a..dcbc2f4586d4 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -1699,7 +1699,6 @@ void arm_iommu_detach_device(struct device *dev) return; } =20 - iommu_detach_device(mapping->domain, dev); kref_put(&mapping->kref, release_iommu_mapping); to_dma_iommu_mapping(dev) =3D NULL; set_dma_ops(dev, NULL); --=20 2.34.1 From nobody Thu Sep 11 16:05:28 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 35406C05027 for ; Fri, 17 Feb 2023 09:56:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230223AbjBQJ4X (ORCPT ); Fri, 17 Feb 2023 04:56:23 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49022 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229950AbjBQJ4P (ORCPT ); Fri, 17 Feb 2023 04:56:15 -0500 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 761785F26D for ; Fri, 17 Feb 2023 01:56:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1676627774; x=1708163774; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=d4ud28FUnLJpp84jaUtvJV6QcvsnVTvJ83pUv/Icsko=; b=l/a/eLMRDOuF+Z2hrozWDRCd33t83agHh7KXITgWApZvsZOtabGJ2UTp PFAloOlXW2j8RkqnPb56Wrzh35vQq9u0GpmV09O2sJpsJc2IitsBvN85H uUUxHdiKdFXcFVg1PRgFBtlmRWwG+ravDLV08vw17MepQUCIlz7JmGVcU yp64vg/30m5S6RkDQRribMUh1l/w+Gffxa2c9xAdXwlP0kjKolPsSapCw RJ7BU00SMM8MyDgtfPPx80Jb56jMgZyZ+tpNuLlJhotQB9KdTAJOOLXJX vI/WbT/tiOmrUV3rM+VDAc+IRu8eAP8R3ME5JqX5T0fINSvmGbNYNu/1b A==; X-IronPort-AV: E=McAfee;i="6500,9779,10623"; a="331955202" X-IronPort-AV: E=Sophos;i="5.97,304,1669104000"; d="scan'208";a="331955202" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Feb 2023 01:56:13 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10623"; a="999391218" X-IronPort-AV: E=Sophos;i="5.97,304,1669104000"; d="scan'208";a="999391218" Received: from allen-box.sh.intel.com ([10.239.159.48]) by fmsmga005.fm.intel.com with ESMTP; 17 Feb 2023 01:56:10 -0800 From: Lu Baolu To: iommu@lists.linux.dev Cc: Joerg Roedel , Jason Gunthorpe , Christoph Hellwig , Kevin Tian , Will Deacon , Robin Murphy , linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v2 2/6] iommu: Split iommu_group_remove_device() into helpers Date: Fri, 17 Feb 2023 17:47:32 +0800 Message-Id: <20230217094736.159005-3-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230217094736.159005-1-baolu.lu@linux.intel.com> References: <20230217094736.159005-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" So that code could be re-used by iommu_release_device() in the subsequent change. No intention for functionality change. Signed-off-by: Lu Baolu --- drivers/iommu/iommu.c | 64 +++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 28c6b088aedd..6247883991e2 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -1069,6 +1069,46 @@ int iommu_group_add_device(struct iommu_group *group= , struct device *dev) } EXPORT_SYMBOL_GPL(iommu_group_add_device); =20 +/* + * Remove a device from a group's device list and return the group device + * if successful. + */ +static struct group_device * +__iommu_group_remove_device(struct iommu_group *group, struct device *dev) +{ + struct group_device *device; + + lockdep_assert_held(&group->mutex); + list_for_each_entry(device, &group->devices, list) { + if (device->dev =3D=3D dev) { + list_del(&device->list); + return device; + } + } + + return NULL; +} + +/* + * Release a device from its group and decrements the iommu group reference + * count. + */ +static void __iommu_group_release_device(struct iommu_group *group, + struct group_device *grp_dev) +{ + struct device *dev =3D grp_dev->dev; + + sysfs_remove_link(group->devices_kobj, grp_dev->name); + sysfs_remove_link(&dev->kobj, "iommu_group"); + + trace_remove_device_from_group(group->id, dev); + + kfree(grp_dev->name); + kfree(grp_dev); + dev->iommu_group =3D NULL; + kobject_put(group->devices_kobj); +} + /** * iommu_group_remove_device - remove a device from it's current group * @dev: device to be removed @@ -1079,7 +1119,7 @@ EXPORT_SYMBOL_GPL(iommu_group_add_device); void iommu_group_remove_device(struct device *dev) { struct iommu_group *group =3D dev->iommu_group; - struct group_device *tmp_device, *device =3D NULL; + struct group_device *device; =20 if (!group) return; @@ -1087,27 +1127,11 @@ void iommu_group_remove_device(struct device *dev) dev_info(dev, "Removing from iommu group %d\n", group->id); =20 mutex_lock(&group->mutex); - list_for_each_entry(tmp_device, &group->devices, list) { - if (tmp_device->dev =3D=3D dev) { - device =3D tmp_device; - list_del(&device->list); - break; - } - } + device =3D __iommu_group_remove_device(group, dev); mutex_unlock(&group->mutex); =20 - if (!device) - return; - - sysfs_remove_link(group->devices_kobj, device->name); - sysfs_remove_link(&dev->kobj, "iommu_group"); - - trace_remove_device_from_group(group->id, dev); - - kfree(device->name); - kfree(device); - dev->iommu_group =3D NULL; - kobject_put(group->devices_kobj); + if (device) + __iommu_group_release_device(group, device); } EXPORT_SYMBOL_GPL(iommu_group_remove_device); =20 --=20 2.34.1 From nobody Thu Sep 11 16:05:28 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 81215C636D4 for ; Fri, 17 Feb 2023 09:56:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229787AbjBQJ43 (ORCPT ); Fri, 17 Feb 2023 04:56:29 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49170 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230203AbjBQJ4S (ORCPT ); Fri, 17 Feb 2023 04:56:18 -0500 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C8D7562FF2 for ; Fri, 17 Feb 2023 01:56:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1676627776; x=1708163776; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=svzPQoaIiOVo1++kdQiL9mjZd3QRrwDo4zYQS1l6NZs=; b=L8PL5LIfdTA32AiWtGMez2yqtM0W+MfFCuUw7O2xE/hoU9R33JtJ9las DhaxIhK5k/uPijXGeB6VzegP7oTR0M+NJ5mLueRXiGbosSrLr+zmlGBul Zd1+/Nva01STpQJHRk9hyKL8CdTM1Qor+wNUoqEWOwP4E2DMmxjPCgieT WnACZ8JcTBvLUY87t2Hj+E5on66Q6EKafpPan2yyeg+Bwr7RDQFqtF/M+ RWoEo9yfqUxJen5x8ihAzNHWpHbEv/JWrMg6kPz8Ijs/wMqBBido9NSTj JlHLpTaKNfWMyOnQsI3JMXvuJjCUVlSg6Ni699gW026PjhaoXXm8mMslt g==; X-IronPort-AV: E=McAfee;i="6500,9779,10623"; a="331955232" X-IronPort-AV: E=Sophos;i="5.97,304,1669104000"; d="scan'208";a="331955232" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Feb 2023 01:56:15 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10623"; a="999391225" X-IronPort-AV: E=Sophos;i="5.97,304,1669104000"; d="scan'208";a="999391225" Received: from allen-box.sh.intel.com ([10.239.159.48]) by fmsmga005.fm.intel.com with ESMTP; 17 Feb 2023 01:56:13 -0800 From: Lu Baolu To: iommu@lists.linux.dev Cc: Joerg Roedel , Jason Gunthorpe , Christoph Hellwig , Kevin Tian , Will Deacon , Robin Murphy , linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v2 3/6] iommu: Same critical region for device release and removal Date: Fri, 17 Feb 2023 17:47:33 +0800 Message-Id: <20230217094736.159005-4-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230217094736.159005-1-baolu.lu@linux.intel.com> References: <20230217094736.159005-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" In a non-driver context, it is crucial to ensure the consistency of a device's iommu ops. Otherwise, it may result in a situation where a device is released but it's iommu ops are still used. Put the ops->release_device and __iommu_group_remove_device() in a some group->mutext critical region, so that, as long as group->mutex is held and the device is in its group's device list, its iommu ops are always consistent. Signed-off-by: Lu Baolu --- drivers/iommu/iommu.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 6247883991e2..093692308b80 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -101,6 +101,10 @@ static int iommu_create_device_direct_mappings(struct = iommu_group *group, static struct iommu_group *iommu_group_get_for_dev(struct device *dev); static ssize_t iommu_group_store_type(struct iommu_group *group, const char *buf, size_t count); +static struct group_device * +__iommu_group_remove_device(struct iommu_group *group, struct device *dev); +static void __iommu_group_release_device(struct iommu_group *group, + struct group_device *grp_dev); =20 #define IOMMU_GROUP_ATTR(_name, _mode, _show, _store) \ struct iommu_group_attribute iommu_group_attr_##_name =3D \ @@ -466,18 +470,25 @@ int iommu_probe_device(struct device *dev) =20 void iommu_release_device(struct device *dev) { + struct iommu_group *group =3D dev->iommu_group; + struct group_device *device; const struct iommu_ops *ops; =20 - if (!dev->iommu) + if (!dev->iommu || !group) return; =20 iommu_device_unlink(dev->iommu->iommu_dev, dev); =20 + mutex_lock(&group->mutex); ops =3D dev_iommu_ops(dev); if (ops->release_device) ops->release_device(dev); + device =3D __iommu_group_remove_device(group, dev); + mutex_unlock(&group->mutex); + + if (device) + __iommu_group_release_device(group, device); =20 - iommu_group_remove_device(dev); module_put(ops->owner); dev_iommu_free(dev); } --=20 2.34.1 From nobody Thu Sep 11 16:05:28 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E3737C05027 for ; Fri, 17 Feb 2023 09:56:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230269AbjBQJ4e (ORCPT ); Fri, 17 Feb 2023 04:56:34 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49232 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230236AbjBQJ42 (ORCPT ); Fri, 17 Feb 2023 04:56:28 -0500 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 360A963BC5 for ; Fri, 17 Feb 2023 01:56:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1676627781; x=1708163781; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=I7zwcHhE0QciS3+BHxkcRCwFeb6U9lVqL1VaFiFdxu8=; b=lODVbbV86Eq4xmxpCfRYhX8gfMppxZYG+8M2uXP4sOyaaOZvn8rFXELX kNwKFfSwVYQGldFw3sBQbUMjAv+Xv6lCSSKoElinWHIN774f0ed7IlVKL Z+w1bqAhGlPcsV/00GRftlii3BYgbp6cveWFcMm5bbHuOVFyNf2IQdjBg U0pux6QPhg44ybPNdB0TCHikeNCuR0Sntxl5RckCehwosVhpyqY83r3DE MeyQYhw9bRZoX0sKJgOakvz8q0fdYzyWHZExREHRyELIHGSZykV4jNcR2 k98F+6SpY5j64gjOlRLH1qZbPR9bfkR8V0RFg6xmx+johxEO7Md5xJriS Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10623"; a="331955258" X-IronPort-AV: E=Sophos;i="5.97,304,1669104000"; d="scan'208";a="331955258" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Feb 2023 01:56:17 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10623"; a="999391230" X-IronPort-AV: E=Sophos;i="5.97,304,1669104000"; d="scan'208";a="999391230" Received: from allen-box.sh.intel.com ([10.239.159.48]) by fmsmga005.fm.intel.com with ESMTP; 17 Feb 2023 01:56:15 -0800 From: Lu Baolu To: iommu@lists.linux.dev Cc: Joerg Roedel , Jason Gunthorpe , Christoph Hellwig , Kevin Tian , Will Deacon , Robin Murphy , linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v2 4/6] iommu: Move lock from iommu_change_dev_def_domain() to its caller Date: Fri, 17 Feb 2023 17:47:34 +0800 Message-Id: <20230217094736.159005-5-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230217094736.159005-1-baolu.lu@linux.intel.com> References: <20230217094736.159005-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The intention is to make it possible to put group ownership check and default domain change in a same critical region protected by the group's mutex lock. No intentional functional change. Signed-off-by: Lu Baolu --- drivers/iommu/iommu.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 093692308b80..e1ae1eb4faf0 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2892,7 +2892,7 @@ static int iommu_change_dev_def_domain(struct iommu_g= roup *group, int ret, dev_def_dom; struct device *dev; =20 - mutex_lock(&group->mutex); + lockdep_assert_held(&group->mutex); =20 if (group->default_domain !=3D group->domain) { dev_err_ratelimited(prev_dev, "Group not assigned to default domain\n"); @@ -2980,28 +2980,15 @@ static int iommu_change_dev_def_domain(struct iommu= _group *group, goto free_new_domain; =20 group->domain =3D group->default_domain; - - /* - * Release the mutex here because ops->probe_finalize() call-back of - * some vendor IOMMU drivers calls arm_iommu_attach_device() which - * in-turn might call back into IOMMU core code, where it tries to take - * group->mutex, resulting in a deadlock. - */ - mutex_unlock(&group->mutex); - - /* Make sure dma_ops is appropriatley set */ - iommu_group_do_probe_finalize(dev, group->default_domain); iommu_domain_free(prev_dom); + return 0; =20 free_new_domain: iommu_domain_free(group->default_domain); group->default_domain =3D prev_dom; group->domain =3D prev_dom; - out: - mutex_unlock(&group->mutex); - return ret; } =20 @@ -3089,7 +3076,19 @@ static ssize_t iommu_group_store_type(struct iommu_g= roup *group, goto out; } =20 + mutex_lock(&group->mutex); ret =3D iommu_change_dev_def_domain(group, dev, req_type); + /* + * Release the mutex here because ops->probe_finalize() call-back of + * some vendor IOMMU drivers calls arm_iommu_attach_device() which + * in-turn might call back into IOMMU core code, where it tries to take + * group->mutex, resulting in a deadlock. + */ + mutex_unlock(&group->mutex); + + /* Make sure dma_ops is appropriatley set */ + if (!ret) + iommu_group_do_probe_finalize(dev, group->default_domain); ret =3D ret ?: count; =20 out: --=20 2.34.1 From nobody Thu Sep 11 16:05:28 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C8DAEC636D4 for ; Fri, 17 Feb 2023 09:56:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229702AbjBQJ4i (ORCPT ); Fri, 17 Feb 2023 04:56:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49170 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230246AbjBQJ43 (ORCPT ); Fri, 17 Feb 2023 04:56:29 -0500 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4317863BC7 for ; Fri, 17 Feb 2023 01:56:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1676627782; x=1708163782; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=01MCM7/CfCIc4vbPRZlHWfdd2YRE/Y7v2MezR4PvnGo=; b=FTPUjJI5z7cfFY7HwLN7oFa546KxeZxAw7qoXeUEO/wFI0eJdUWNcxa7 WAqk4NnZHnRG9DqE0yCD/ZIuADrFN9RO3fUkLDlyZzoaXjeW3bgZmgU/7 trPP5mWxRmVcpfGsoQY3agY6877mpDzEui/b3/y9ia7jLjPmiqhBeD5d2 ksfvJFoaD/lU6Rd2hZShScz3WeWiDw5IiJSGimUzCnLm2fkTdq6sHNBKB AiWs7OzBLi7eiluS/+5C3nYo4bw3S8Lst/TKgNWYgjFBuN/2YOESxUhYQ YHXHBbgJGjxPvrV21y+7oPqCPbn4ecvzjeo2mZr1OtAhRlefu+jL/iLnx w==; X-IronPort-AV: E=McAfee;i="6500,9779,10623"; a="331955279" X-IronPort-AV: E=Sophos;i="5.97,304,1669104000"; d="scan'208";a="331955279" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Feb 2023 01:56:19 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10623"; a="999391235" X-IronPort-AV: E=Sophos;i="5.97,304,1669104000"; d="scan'208";a="999391235" Received: from allen-box.sh.intel.com ([10.239.159.48]) by fmsmga005.fm.intel.com with ESMTP; 17 Feb 2023 01:56:17 -0800 From: Lu Baolu To: iommu@lists.linux.dev Cc: Joerg Roedel , Jason Gunthorpe , Christoph Hellwig , Kevin Tian , Will Deacon , Robin Murphy , linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v2 5/6] iommu: Replace device_lock() with group->mutex Date: Fri, 17 Feb 2023 17:47:35 +0800 Message-Id: <20230217094736.159005-6-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230217094736.159005-1-baolu.lu@linux.intel.com> References: <20230217094736.159005-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" device_lock() was used in iommu_group_store_type() to prevent the devices in an iommu group from being attached by any device driver. On the other hand, in order to avoid lock race between group->mutex and device_lock(), it limited the usage scenario to the singleton groups. We already have the DMA ownership scheme to avoid driver attachment and group->mutex ensures that device ops are always valid, there's no need for device_lock() anymore. Remove device_lock() and the singleton group limitation. Signed-off-by: Lu Baolu --- drivers/iommu/iommu.c | 78 +++++++++---------------------------------- 1 file changed, 16 insertions(+), 62 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index e1ae1eb4faf0..18dac155a178 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2958,14 +2958,6 @@ static int iommu_change_dev_def_domain(struct iommu_= group *group, goto out; } =20 - /* We can bring up a flush queue without tearing down the domain */ - if (type =3D=3D IOMMU_DOMAIN_DMA_FQ && prev_dom->type =3D=3D IOMMU_DOMAIN= _DMA) { - ret =3D iommu_dma_init_fq(prev_dom); - if (!ret) - prev_dom->type =3D IOMMU_DOMAIN_DMA_FQ; - goto out; - } - /* Sets group->default_domain to the newly allocated domain */ ret =3D iommu_group_alloc_default_domain(group, dev, type); if (ret) @@ -2998,7 +2990,7 @@ static int iommu_change_dev_def_domain(struct iommu_g= roup *group, * transition. Return failure if this isn't met. * * We need to consider the race between this and the device release path. - * device_lock(dev) is used here to guarantee that the device release path + * group->mutex is used here to guarantee that the device release path * will not be entered at the same time. */ static ssize_t iommu_group_store_type(struct iommu_group *group, @@ -3024,60 +3016,27 @@ static ssize_t iommu_group_store_type(struct iommu_= group *group, else return -EINVAL; =20 - /* - * Lock/Unlock the group mutex here before device lock to - * 1. Make sure that the iommu group has only one device (this is a - * prerequisite for step 2) - * 2. Get struct *dev which is needed to lock device - */ mutex_lock(&group->mutex); - if (iommu_group_device_count(group) !=3D 1) { + /* We can bring up a flush queue without tearing down the domain. */ + if (req_type =3D=3D IOMMU_DOMAIN_DMA_FQ && + group->default_domain->type =3D=3D IOMMU_DOMAIN_DMA) { + ret =3D iommu_dma_init_fq(group->default_domain); + if (!ret) + group->default_domain->type =3D IOMMU_DOMAIN_DMA_FQ; mutex_unlock(&group->mutex); - pr_err_ratelimited("Cannot change default domain: Group has more than on= e device\n"); - return -EINVAL; + + return ret ?: count; } =20 - /* Since group has only one device */ + /* Otherwise, ensure that device exists and no driver is bound. */ dev =3D iommu_group_first_dev(group); - get_device(dev); - - /* - * Don't hold the group mutex because taking group mutex first and then - * the device lock could potentially cause a deadlock as below. Assume - * two threads T1 and T2. T1 is trying to change default domain of an - * iommu group and T2 is trying to hot unplug a device or release [1] VF - * of a PCIe device which is in the same iommu group. T1 takes group - * mutex and before it could take device lock assume T2 has taken device - * lock and is yet to take group mutex. Now, both the threads will be - * waiting for the other thread to release lock. Below, lock order was - * suggested. - * device_lock(dev); - * mutex_lock(&group->mutex); - * iommu_change_dev_def_domain(); - * mutex_unlock(&group->mutex); - * device_unlock(dev); - * - * [1] Typical device release path - * device_lock() from device/driver core code - * -> bus_notifier() - * -> iommu_bus_notifier() - * -> iommu_release_device() - * -> ops->release_device() vendor driver calls back iommu core code - * -> mutex_lock() from iommu core code - */ - mutex_unlock(&group->mutex); - - /* Check if the device in the group still has a driver bound to it */ - device_lock(dev); - if (device_is_bound(dev) && !(req_type =3D=3D IOMMU_DOMAIN_DMA_FQ && - group->default_domain->type =3D=3D IOMMU_DOMAIN_DMA)) { - pr_err_ratelimited("Device is still bound to driver\n"); - ret =3D -EBUSY; - goto out; + if (!dev || group->owner_cnt) { + mutex_unlock(&group->mutex); + return -EPERM; } =20 - mutex_lock(&group->mutex); ret =3D iommu_change_dev_def_domain(group, dev, req_type); + /* * Release the mutex here because ops->probe_finalize() call-back of * some vendor IOMMU drivers calls arm_iommu_attach_device() which @@ -3088,14 +3047,9 @@ static ssize_t iommu_group_store_type(struct iommu_g= roup *group, =20 /* Make sure dma_ops is appropriatley set */ if (!ret) - iommu_group_do_probe_finalize(dev, group->default_domain); - ret =3D ret ?: count; - -out: - device_unlock(dev); - put_device(dev); + __iommu_group_dma_finalize(group); =20 - return ret; + return ret ?: count; } =20 static bool iommu_is_default_domain(struct iommu_group *group) --=20 2.34.1 From nobody Thu Sep 11 16:05:28 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 717A4C05027 for ; Fri, 17 Feb 2023 09:56:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230289AbjBQJ4l (ORCPT ); Fri, 17 Feb 2023 04:56:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49200 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230254AbjBQJ43 (ORCPT ); Fri, 17 Feb 2023 04:56:29 -0500 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3565D6243C for ; Fri, 17 Feb 2023 01:56:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1676627783; x=1708163783; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=L0BLlBlx7/lIGCWsyetXVIlqgQEx+QKVJ6i4zLx6NnI=; b=Md1qDKVQACDyefwtH6zjbVYoiUT4gHvZhbYcHlc4NCwi01V93GWgjr2G oJZJi3rINceIgOnHddEgC1NrTPo8aoGFBaU4bTnOdQI4XoaHblcAJtoUn I/KTKMpBNmh4OkaI6mlyHdS14hEaNVFQk61zN4hkUbg1Pdz7snqzuLq1D NfD9MDvMTJ+2lJUuqk55/KyPZz1Grxl8RupLloSQVQx66jYvJRMS/elBj xHUd9uk0Vqx0rfJPeU3rRsCylbBqfL6Ns7SqRs7XK6cLO6O6fEDrwHrAb prvGCkbQZhTd9WGRoHtSgLya89HDOWimaXmyVkHZuunHiGTBNTwUelRKN A==; X-IronPort-AV: E=McAfee;i="6500,9779,10623"; a="331955298" X-IronPort-AV: E=Sophos;i="5.97,304,1669104000"; d="scan'208";a="331955298" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Feb 2023 01:56:21 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10623"; a="999391241" X-IronPort-AV: E=Sophos;i="5.97,304,1669104000"; d="scan'208";a="999391241" Received: from allen-box.sh.intel.com ([10.239.159.48]) by fmsmga005.fm.intel.com with ESMTP; 17 Feb 2023 01:56:19 -0800 From: Lu Baolu To: iommu@lists.linux.dev Cc: Joerg Roedel , Jason Gunthorpe , Christoph Hellwig , Kevin Tian , Will Deacon , Robin Murphy , linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v2 6/6] iommu: Cleanup iommu_change_dev_def_domain() Date: Fri, 17 Feb 2023 17:47:36 +0800 Message-Id: <20230217094736.159005-7-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230217094736.159005-1-baolu.lu@linux.intel.com> References: <20230217094736.159005-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" As the singleton group limitation has been removed, cleanup the code in iommu_change_dev_def_domain() accordingly. Documentation is also updated. Signed-off-by: Lu Baolu --- drivers/iommu/iommu.c | 81 +++++-------------- .../ABI/testing/sysfs-kernel-iommu_groups | 1 - 2 files changed, 21 insertions(+), 61 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 18dac155a178..c06757224bec 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2871,11 +2871,10 @@ int iommu_dev_disable_feature(struct device *dev, e= num iommu_dev_features feat) EXPORT_SYMBOL_GPL(iommu_dev_disable_feature); =20 /* - * Changes the default domain of an iommu group that has *only* one device + * Changes the default domain of an iommu group * * @group: The group for which the default domain should be changed - * @prev_dev: The device in the group (this is used to make sure that the = device - * hasn't changed after the caller has called this function) + * @dev: The first device in the group * @type: The type of the new default domain that gets associated with the= group * * Returns 0 on success and error code on failure @@ -2886,101 +2885,63 @@ EXPORT_SYMBOL_GPL(iommu_dev_disable_feature); * Please take a closer look if intended to use for other purposes. */ static int iommu_change_dev_def_domain(struct iommu_group *group, - struct device *prev_dev, int type) + struct device *dev, int type) { + struct __group_domain_type gtype =3D {NULL, 0}; struct iommu_domain *prev_dom; - int ret, dev_def_dom; - struct device *dev; + int ret; =20 lockdep_assert_held(&group->mutex); =20 - if (group->default_domain !=3D group->domain) { - dev_err_ratelimited(prev_dev, "Group not assigned to default domain\n"); - ret =3D -EBUSY; - goto out; - } - - /* - * iommu group wasn't locked while acquiring device lock in - * iommu_group_store_type(). So, make sure that the device count hasn't - * changed while acquiring device lock. - * - * Changing default domain of an iommu group with two or more devices - * isn't supported because there could be a potential deadlock. Consider - * the following scenario. T1 is trying to acquire device locks of all - * the devices in the group and before it could acquire all of them, - * there could be another thread T2 (from different sub-system and use - * case) that has already acquired some of the device locks and might be - * waiting for T1 to release other device locks. - */ - if (iommu_group_device_count(group) !=3D 1) { - dev_err_ratelimited(prev_dev, "Cannot change default domain: Group has m= ore than one device\n"); - ret =3D -EINVAL; - goto out; - } - - /* Since group has only one device */ - dev =3D iommu_group_first_dev(group); - - if (prev_dev !=3D dev) { - dev_err_ratelimited(prev_dev, "Cannot change default domain: Device has = been changed\n"); - ret =3D -EBUSY; - goto out; - } - prev_dom =3D group->default_domain; - if (!prev_dom) { - ret =3D -EINVAL; - goto out; - } - - dev_def_dom =3D iommu_get_def_domain_type(dev); + __iommu_group_for_each_dev(group, >ype, + probe_get_default_domain_type); if (!type) { /* * If the user hasn't requested any specific type of domain and * if the device supports both the domains, then default to the * domain the device was booted with */ - type =3D dev_def_dom ? : iommu_def_domain_type; - } else if (dev_def_dom && type !=3D dev_def_dom) { - dev_err_ratelimited(prev_dev, "Device cannot be in %s domain\n", + type =3D gtype.type ? : iommu_def_domain_type; + } else if (gtype.type && type !=3D gtype.type) { + dev_err_ratelimited(dev, "Device cannot be in %s domain\n", iommu_domain_type_str(type)); - ret =3D -EINVAL; - goto out; + return -EINVAL; } =20 /* * Switch to a new domain only if the requested domain type is different * from the existing default domain type */ - if (prev_dom->type =3D=3D type) { - ret =3D 0; - goto out; - } + if (prev_dom->type =3D=3D type) + return 0; + + group->default_domain =3D NULL; + group->domain =3D NULL; =20 /* Sets group->default_domain to the newly allocated domain */ ret =3D iommu_group_alloc_default_domain(group, dev, type); if (ret) - goto out; + goto restore_old_domain; =20 - ret =3D iommu_create_device_direct_mappings(group, dev); + ret =3D iommu_group_create_direct_mappings(group); if (ret) goto free_new_domain; =20 - ret =3D __iommu_attach_device(group->default_domain, dev); + ret =3D __iommu_attach_group(group->default_domain, group); if (ret) goto free_new_domain; =20 - group->domain =3D group->default_domain; iommu_domain_free(prev_dom); =20 return 0; =20 free_new_domain: iommu_domain_free(group->default_domain); +restore_old_domain: group->default_domain =3D prev_dom; group->domain =3D prev_dom; -out: + return ret; } =20 diff --git a/Documentation/ABI/testing/sysfs-kernel-iommu_groups b/Document= ation/ABI/testing/sysfs-kernel-iommu_groups index b15af6a5bc08..a42d4383d999 100644 --- a/Documentation/ABI/testing/sysfs-kernel-iommu_groups +++ b/Documentation/ABI/testing/sysfs-kernel-iommu_groups @@ -53,7 +53,6 @@ Description: /sys/kernel/iommu_groups//type shows= the type of default =20 The default domain type of a group may be modified only when =20 - - The group has only one device. - The device in the group is not bound to any device driver. So, the users must unbind the appropriate driver before changing the default domain type. --=20 2.34.1