From nobody Thu Sep 11 16:05:29 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 B69FCC6FD1C for ; Wed, 22 Mar 2023 06:49:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229676AbjCVGtw (ORCPT ); Wed, 22 Mar 2023 02:49:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58788 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229668AbjCVGtl (ORCPT ); Wed, 22 Mar 2023 02:49:41 -0400 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AF83D298DD for ; Tue, 21 Mar 2023 23:49:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1679467779; x=1711003779; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=0RHdVtmElNj1Gz3aelx3dDSWLuFTYKQB4XyswkTwt0o=; b=PvvFIovksJ61RoIEXoaG6TUkvq6UYSfpn8WKX+vCpmAlUVWckcxSc6zS t6iDHmHBoxfLCLiXgnO1OSJOYREMaNjbq9NpImo1t38vEuWr7bUajlSi/ CNGLmFQTvshP/8qUet4A1PEppIP4+T/Dp0cH2TADUf0NsUFeHpsDabIty PvPBydBL8AeN2FXkYyR2YgjdMh+7V8zqjrJ87F5oZ4QaTPxPSxv/l4Jz5 6gYu1JJ3lxgblKsLwAbRq6/iRw5r9XoJAJM7nsMestfUrS5lNzdlLrJGy WjpHSN/zwZoZa13RAD26srhkQrXZWjg0q0vmjAVF7Qeo+aM9sEHVuSnI7 Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10656"; a="337866725" X-IronPort-AV: E=Sophos;i="5.98,281,1673942400"; d="scan'208";a="337866725" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Mar 2023 23:49:39 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10656"; a="659080374" X-IronPort-AV: E=Sophos;i="5.98,281,1673942400"; d="scan'208";a="659080374" Received: from allen-box.sh.intel.com ([10.239.159.48]) by orsmga006.jf.intel.com with ESMTP; 21 Mar 2023 23:49:36 -0700 From: Lu Baolu To: Joerg Roedel Cc: Jason Gunthorpe , Robin Murphy , Christoph Hellwig , Kevin Tian , Will Deacon , iommu@lists.linux.dev, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v4 1/6] iommu/ipmmu-vmsa: Call arm_iommu_release_mapping() in release path Date: Wed, 22 Mar 2023 14:49:51 +0800 Message-Id: <20230322064956.263419-2-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230322064956.263419-1-baolu.lu@linux.intel.com> References: <20230322064956.263419-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 the iommu driver's release_device operation, the driver should detach the device from any attached domain and release the resources allocated in the probe_device and probe_finalize paths. Replace arm_iommu_detach_device() with arm_iommu_release_mapping() in the release path of the ipmmu-vmsa driver. The device_release callback is called in device_del(), this device is not coming back. Zeroing out pointers and testing for a condition which cannot be true by construction is simply a waste of time and 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: Jason Gunthorpe Suggested-by: Robin Murphy Link: https://lore.kernel.org/linux-iommu/7b248ba1-3967-5cd8-82e9-0268c706d= 320@arm.com/ Signed-off-by: Lu Baolu Reviewed-by: Jason Gunthorpe --- drivers/iommu/ipmmu-vmsa.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index bdf1a4e5eae0..bc135679523a 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c @@ -30,7 +30,6 @@ #define arm_iommu_create_mapping(...) NULL #define arm_iommu_attach_device(...) -ENODEV #define arm_iommu_release_mapping(...) do {} while (0) -#define arm_iommu_detach_device(...) do {} while (0) #endif =20 #define IPMMU_CTX_MAX 16U @@ -820,7 +819,18 @@ static void ipmmu_probe_finalize(struct device *dev) =20 static void ipmmu_release_device(struct device *dev) { - arm_iommu_detach_device(dev); + struct iommu_fwspec *fwspec =3D dev_iommu_fwspec_get(dev); + struct ipmmu_vmsa_device *mmu =3D to_ipmmu(dev); + unsigned int i; + + for (i =3D 0; i < fwspec->num_ids; ++i) { + unsigned int utlb =3D fwspec->ids[i]; + + ipmmu_imuctr_write(mmu, utlb, 0); + mmu->utlb_ctx[utlb] =3D IPMMU_CTX_INVALID; + } + + arm_iommu_release_mapping(mmu->mapping); } =20 static struct iommu_group *ipmmu_find_group(struct device *dev) --=20 2.34.1 From nobody Thu Sep 11 16:05:29 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 453E6C6FD1C for ; Wed, 22 Mar 2023 06:49:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229999AbjCVGty (ORCPT ); Wed, 22 Mar 2023 02:49:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59188 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229917AbjCVGts (ORCPT ); Wed, 22 Mar 2023 02:49:48 -0400 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0E61425E16 for ; Tue, 21 Mar 2023 23:49:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1679467782; x=1711003782; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=uNsJ5iL/12Ebvb4ULP39bZOjdt78s0sC7JK9D/nWeI8=; b=nsUX9bYD2DpX7olHGN04k+04liza5iIcQfq0BRWVcWWhhCq2CmWOXP16 OM2cFxwEihXAl5nRufdgKlSoKYqYQ5UiW3C7IiUKD3EMpQR6wcTCoxB+x 8QTCvOQEQrJf4COt5f3zQmjgDrdWPYriI1cQULiGLcwtvj7IMjK956871 ZKP8be7Ixiqi5o237sdILGvQWIfzRcvPj7udQr/l6jgZwzKVRK+SRC1mr 81MNRIZqXjOuoF+NIqSosgyo+siLs9kaBW452Z1R4iknzyAkWIpNpscFz hEOYLOE9KNH65T3Nz7Q27EgOzezOrQ0GH8/8vdB/nbsMzNbA/L46V3vii Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10656"; a="337866739" X-IronPort-AV: E=Sophos;i="5.98,281,1673942400"; d="scan'208";a="337866739" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Mar 2023 23:49:41 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10656"; a="659080394" X-IronPort-AV: E=Sophos;i="5.98,281,1673942400"; d="scan'208";a="659080394" Received: from allen-box.sh.intel.com ([10.239.159.48]) by orsmga006.jf.intel.com with ESMTP; 21 Mar 2023 23:49:39 -0700 From: Lu Baolu To: Joerg Roedel Cc: Jason Gunthorpe , Robin Murphy , Christoph Hellwig , Kevin Tian , Will Deacon , iommu@lists.linux.dev, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v4 2/6] iommu: Split iommu_group_remove_device() into helpers Date: Wed, 22 Mar 2023 14:49:52 +0800 Message-Id: <20230322064956.263419-3-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230322064956.263419-1-baolu.lu@linux.intel.com> References: <20230322064956.263419-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: Jason Gunthorpe Signed-off-by: Lu Baolu Reviewed-by: Jason Gunthorpe --- 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 10db680acaed..43db48323370 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -453,6 +453,46 @@ int iommu_probe_device(struct device *dev) =20 } =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); +} + void iommu_release_device(struct device *dev) { const struct iommu_ops *ops; @@ -1068,7 +1108,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; @@ -1076,27 +1116,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:29 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 936D6C6FD1C for ; Wed, 22 Mar 2023 06:50:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229802AbjCVGt5 (ORCPT ); Wed, 22 Mar 2023 02:49:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59156 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230013AbjCVGtt (ORCPT ); Wed, 22 Mar 2023 02:49:49 -0400 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A482B367DE for ; Tue, 21 Mar 2023 23:49:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1679467784; x=1711003784; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=hPoFlztxY1xJolSJngRYhbNVr0XuleACaIwXyUztnXE=; b=aBG04VrZKokFBcyU+1BnPnYUTzhzioux6cvGYIBESxAHe/OhgAQvYKSD XUOCzliuCpMqUYC68C2iuMDVQz/ynD0WwHnl+Xpi3QoENSXKuzk6R/hn7 UbZkZtK/0UBLaBiBjZ5mY+P3SdTRjwHw7N1vK7gIu1sYhzm9OcAqzJTXL xrhG0LIbr6epBSnhUkEQ43DxYJCINvdSa6N+KPsyLPmkLocwTgr5l1J2K hifFuCmpBRr7w2kg/kaKEjvq0PKd6tX86lQMmVOu9f4KP/jmZ8sVNhuQw W6cyKaRvkyvTMnvV/o9TqhC9xWh3pysq5NCScg3kKdsT1BNRMI7BGwnlD A==; X-IronPort-AV: E=McAfee;i="6600,9927,10656"; a="337866752" X-IronPort-AV: E=Sophos;i="5.98,281,1673942400"; d="scan'208";a="337866752" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Mar 2023 23:49:44 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10656"; a="659080417" X-IronPort-AV: E=Sophos;i="5.98,281,1673942400"; d="scan'208";a="659080417" Received: from allen-box.sh.intel.com ([10.239.159.48]) by orsmga006.jf.intel.com with ESMTP; 21 Mar 2023 23:49:41 -0700 From: Lu Baolu To: Joerg Roedel Cc: Jason Gunthorpe , Robin Murphy , Christoph Hellwig , Kevin Tian , Will Deacon , iommu@lists.linux.dev, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v4 3/6] iommu: Same critical region for device release and removal Date: Wed, 22 Mar 2023 14:49:53 +0800 Message-Id: <20230322064956.263419-4-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230322064956.263419-1-baolu.lu@linux.intel.com> References: <20230322064956.263419-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 same 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. Add check of group ownership if the released device is the last one. Signed-off-by: Jason Gunthorpe Signed-off-by: Lu Baolu Reviewed-by: Jason Gunthorpe --- drivers/iommu/iommu.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 43db48323370..6d27fd585e75 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -495,18 +495,44 @@ static void __iommu_group_release_device(struct iommu= _group *group, =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); + device =3D __iommu_group_remove_device(group, dev); + + /* + * If the group has become empty then ownership must have been released, + * and the current domain must be set back to NULL or the default + * domain. + */ + if (list_empty(&group->devices)) + WARN_ON(group->owner_cnt || + group->domain !=3D group->default_domain); + + /* + * release_device() must stop using any attached domain on the device. + * If there are still other devices in the group they are not effected + * by this callback. + * + * The IOMMU driver must set the device to either an identity or + * blocking translation and stop using any domain pointer, as it is + * going to be freed. + */ ops =3D dev_iommu_ops(dev); if (ops->release_device) ops->release_device(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:29 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 26EECC74A5B for ; Wed, 22 Mar 2023 06:50:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229739AbjCVGuS (ORCPT ); Wed, 22 Mar 2023 02:50:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59476 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229784AbjCVGtx (ORCPT ); Wed, 22 Mar 2023 02:49:53 -0400 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 10E9156516 for ; Tue, 21 Mar 2023 23:49:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1679467787; x=1711003787; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=xP7VJduO7JMRCBdiR2gq1cP4nZMZAj/onHcGkgWCalY=; b=ayBn1ds8RFyAxQp+wWXjXPkcmCzhkNqA8UNBFBTb4MRkegi8wIXvSFUt 83hL8CV+d7Yd4JSPmF6p0r+Ldof+DrcbUhfAoKNOmKiAntVLiDxLJY4Wa 8ewzdzM3FzZsZzHTt0sgsWyfGqIN170kOuelPZs9+8IOTpP752VuUPPY6 aWtepSWmSzfxjdAd+nDRXB+g4SR3V0hCsarI6E9t4wC5o9FE0qqhc1QRT NIwgCHdWG/FUJ1J0xkV0tlD8PGKuycMy1AqmViGNfIHYP47bAVbAguxpY zSCyk/rBKFi3SAp9FayG4VAsbQibVc3HfWrhDvBaJPp8OrHYHH1yCiHmu w==; X-IronPort-AV: E=McAfee;i="6600,9927,10656"; a="337866763" X-IronPort-AV: E=Sophos;i="5.98,281,1673942400"; d="scan'208";a="337866763" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Mar 2023 23:49:46 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10656"; a="659080433" X-IronPort-AV: E=Sophos;i="5.98,281,1673942400"; d="scan'208";a="659080433" Received: from allen-box.sh.intel.com ([10.239.159.48]) by orsmga006.jf.intel.com with ESMTP; 21 Mar 2023 23:49:44 -0700 From: Lu Baolu To: Joerg Roedel Cc: Jason Gunthorpe , Robin Murphy , Christoph Hellwig , Kevin Tian , Will Deacon , iommu@lists.linux.dev, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v4 4/6] iommu: Move lock from iommu_change_dev_def_domain() to its caller Date: Wed, 22 Mar 2023 14:49:54 +0800 Message-Id: <20230322064956.263419-5-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230322064956.263419-1-baolu.lu@linux.intel.com> References: <20230322064956.263419-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 Reviewed-by: Jason Gunthorpe --- 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 6d27fd585e75..54a5bd79d21b 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2889,7 +2889,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"); @@ -2978,28 +2978,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:29 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 9E364C6FD1C for ; Wed, 22 Mar 2023 06:50:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229827AbjCVGuZ (ORCPT ); Wed, 22 Mar 2023 02:50:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59844 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230021AbjCVGt7 (ORCPT ); Wed, 22 Mar 2023 02:49:59 -0400 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DDB1E5BC8C for ; Tue, 21 Mar 2023 23:49:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1679467789; x=1711003789; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Il0exbOKWwaeUfCP7sZnohPbX01OZ44X03V9nAnokQM=; b=UedqOQ66rrzQSu7kZL34CBz3UN+8XCCxdBgPrAsz4i5CrEL7x5EmUFh7 QekXPqGUygSMG5xnt/XYHHLFDoWprxhTBimsF4RNISvhBQmLV6bQ2zZkS j1aieGbyL0mlAWDHGgr4+KIW6MF4FyizEjErB1uKHWliIkCQXbVnGeZPm PJ+iVPreWps1+iUfDmByu/dy15fnNQ1MzKW7djsajFQ2XPbPKVLDrtUqR TxMNr3YsefAbkvuUQKjDgl0xdLCoSRzhChf9w/FQ1Cvj1wBrvMEx0nY1X 5E8AhKP4cvTojNeyrgvElsMDkfY/YzkBo9PXB6iVs8i+Ic5Id3bbl+RkC A==; X-IronPort-AV: E=McAfee;i="6600,9927,10656"; a="337866775" X-IronPort-AV: E=Sophos;i="5.98,281,1673942400"; d="scan'208";a="337866775" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Mar 2023 23:49:49 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10656"; a="659080448" X-IronPort-AV: E=Sophos;i="5.98,281,1673942400"; d="scan'208";a="659080448" Received: from allen-box.sh.intel.com ([10.239.159.48]) by orsmga006.jf.intel.com with ESMTP; 21 Mar 2023 23:49:46 -0700 From: Lu Baolu To: Joerg Roedel Cc: Jason Gunthorpe , Robin Murphy , Christoph Hellwig , Kevin Tian , Will Deacon , iommu@lists.linux.dev, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v4 5/6] iommu: Replace device_lock() with group->mutex Date: Wed, 22 Mar 2023 14:49:55 +0800 Message-Id: <20230322064956.263419-6-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230322064956.263419-1-baolu.lu@linux.intel.com> References: <20230322064956.263419-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 Reviewed-by: Jason Gunthorpe --- drivers/iommu/iommu.c | 81 ++++++++++--------------------------------- 1 file changed, 18 insertions(+), 63 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 54a5bd79d21b..b780cdddf415 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2956,14 +2956,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(dev->bus, group, type); if (ret) @@ -2996,7 +2988,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, @@ -3023,61 +3015,29 @@ 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; + } + + /* Otherwise, ensure that device exists and no driver is bound. */ + if (list_empty(&group->devices) || group->owner_cnt) { + mutex_unlock(&group->mutex); + return -EPERM; } =20 - /* Since group has only one device */ grp_dev =3D list_first_entry(&group->devices, struct group_device, list); dev =3D grp_dev->dev; - get_device(dev); =20 - /* - * 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; - } - - 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 +3048,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:29 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 668CFC6FD1F for ; Wed, 22 Mar 2023 06:50:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229717AbjCVGu2 (ORCPT ); Wed, 22 Mar 2023 02:50:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59572 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230105AbjCVGuJ (ORCPT ); Wed, 22 Mar 2023 02:50:09 -0400 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C1DC32B9EA for ; Tue, 21 Mar 2023 23:49:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1679467792; x=1711003792; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=5/QtRJNGbVy0gqEC5sJtBu3RE6LTB+TTy8zzoXdzsNA=; b=YtPG9MeTu8t46wv4wJrQqSXA6SDKhO9V9yjOsVm/ILmBHgM1I2hYNOlu ulHfTmfjJ3gFDKxWVLxVxEFDO/6bZV4Y7MPPaSf707mZX83cOQpNUzupo Yz9775Ir1NNjpb0owfDawmPqe+VVNbhvEHKW83XkrnBvARbaEX4IG2Bnt lMBftsHtquAaoqhMerBPRcQ+9V874O6QM0dowY2WdmIsDK9tGV+WQa68J 2PS/Rn9PQZoOu5ZfQMuDA5/pdyjpnQGyemzOdxLe0/msqr3PqhUvDsVAR BuyzGrxp+F1s1MTD2qA1JPyax6nQcADzNONFV48Tzr/eBMJTwD/KyjWZV A==; X-IronPort-AV: E=McAfee;i="6600,9927,10656"; a="337866787" X-IronPort-AV: E=Sophos;i="5.98,281,1673942400"; d="scan'208";a="337866787" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Mar 2023 23:49:52 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10656"; a="659080461" X-IronPort-AV: E=Sophos;i="5.98,281,1673942400"; d="scan'208";a="659080461" Received: from allen-box.sh.intel.com ([10.239.159.48]) by orsmga006.jf.intel.com with ESMTP; 21 Mar 2023 23:49:49 -0700 From: Lu Baolu To: Joerg Roedel Cc: Jason Gunthorpe , Robin Murphy , Christoph Hellwig , Kevin Tian , Will Deacon , iommu@lists.linux.dev, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH v4 6/6] iommu: Cleanup iommu_change_dev_def_domain() Date: Wed, 22 Mar 2023 14:49:56 +0800 Message-Id: <20230322064956.263419-7-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230322064956.263419-1-baolu.lu@linux.intel.com> References: <20230322064956.263419-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 Reviewed-by: Jason Gunthorpe --- drivers/iommu/iommu.c | 83 +++++-------------- .../ABI/testing/sysfs-kernel-iommu_groups | 1 - 2 files changed, 21 insertions(+), 63 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index b780cdddf415..a38b9f279c5d 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2867,11 +2867,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 @@ -2882,103 +2881,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; - struct group_device *grp_dev; - 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 */ - grp_dev =3D list_first_entry(&group->devices, struct group_device, list); - dev =3D grp_dev->dev; - - 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(dev->bus, group, 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