From nobody Sun Sep 14 16:23:34 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 63857C004D4 for ; Thu, 19 Jan 2023 19:20:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231401AbjASTUY (ORCPT ); Thu, 19 Jan 2023 14:20:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59976 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231565AbjASTUD (ORCPT ); Thu, 19 Jan 2023 14:20:03 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 3752F9EE07 for ; Thu, 19 Jan 2023 11:19:11 -0800 (PST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 7B3E41758; Thu, 19 Jan 2023 11:19:23 -0800 (PST) Received: from e121345-lin.cambridge.arm.com (e121345-lin.cambridge.arm.com [10.1.196.40]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 312DD3F67D; Thu, 19 Jan 2023 11:18:41 -0800 (PST) From: Robin Murphy To: joro@8bytes.org, will@kernel.org Cc: hch@lst.de, jgg@nvidia.com, iommu@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH 1/8] iommu: Decouple iommu_present() from bus ops Date: Thu, 19 Jan 2023 19:18:19 +0000 Message-Id: <1fb168b22cbbb5c24162d29d2a9aca339cda2c72.1673978700.git.robin.murphy@arm.com> X-Mailer: git-send-email 2.36.1.dirty In-Reply-To: References: 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" Much as I'd like to remove iommu_present(), the final remaining users are proving stubbornly difficult to clean up, so kick that can down the road and just rework it to preserve the current behaviour without depending on bus ops. Signed-off-by: Robin Murphy --- drivers/iommu/iommu.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index b189ed345057..a77d58e1b976 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -1871,9 +1871,24 @@ int bus_iommu_probe(struct bus_type *bus) return ret; } =20 +static int __iommu_present(struct device *dev, void *unused) +{ + return device_iommu_mapped(dev); +} + +/** + * iommu_present() - make platform-specific assumptions about an IOMMU + * @bus: bus to check + * + * Do not use this function. You want device_iommu_mapped() instead. + * + * Return: true if some IOMMU is present for some device on the given bus.= In + * general it may not be the only IOMMU, and it may not be for the device = you + * are ultimately interested in. + */ bool iommu_present(struct bus_type *bus) { - return bus->iommu_ops !=3D NULL; + return bus_for_each_dev(bus, NULL, NULL, __iommu_present) > 0; } EXPORT_SYMBOL_GPL(iommu_present); =20 --=20 2.36.1.dirty From nobody Sun Sep 14 16:23:34 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 919A4C46467 for ; Thu, 19 Jan 2023 19:20:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231424AbjASTU1 (ORCPT ); Thu, 19 Jan 2023 14:20:27 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60330 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231577AbjASTUD (ORCPT ); Thu, 19 Jan 2023 14:20:03 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 37E819EE20 for ; Thu, 19 Jan 2023 11:19:12 -0800 (PST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 9188B1BB2; Thu, 19 Jan 2023 11:19:24 -0800 (PST) Received: from e121345-lin.cambridge.arm.com (e121345-lin.cambridge.arm.com [10.1.196.40]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 2D00E3F67D; Thu, 19 Jan 2023 11:18:42 -0800 (PST) From: Robin Murphy To: joro@8bytes.org, will@kernel.org Cc: hch@lst.de, jgg@nvidia.com, iommu@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH 2/8] iommu: Validate that devices match domains Date: Thu, 19 Jan 2023 19:18:20 +0000 Message-Id: <3690e5e6b53f6bfecd56f2e0aa77d2915f2e2588.1673978700.git.robin.murphy@arm.com> X-Mailer: git-send-email 2.36.1.dirty In-Reply-To: References: 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" Before we can allow drivers to coexist, we need to make sure that one driver's domain ops can't misinterpret another driver's dev_iommu_priv data. To that end, add a token to the domain so we can remember how it was allocated - for now this may as well be the device ops. We can trust ourselves for internal default domain attachment, so add the check where it covers both the external attach interfaces. Signed-off-by: Robin Murphy --- drivers/iommu/iommu.c | 13 +++++++++---- include/linux/iommu.h | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index a77d58e1b976..bc53ffbba4de 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -1941,20 +1941,22 @@ EXPORT_SYMBOL_GPL(iommu_set_fault_handler); static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus, unsigned type) { + const struct iommu_ops *ops =3D bus ? bus->iommu_ops : NULL; struct iommu_domain *domain; =20 - if (bus =3D=3D NULL || bus->iommu_ops =3D=3D NULL) + if (!ops) return NULL; =20 - domain =3D bus->iommu_ops->domain_alloc(type); + domain =3D ops->domain_alloc(type); if (!domain) return NULL; =20 domain->type =3D type; + domain->owner =3D ops; /* Assume all sizes by default; the driver may override this later */ - domain->pgsize_bitmap =3D bus->iommu_ops->pgsize_bitmap; + domain->pgsize_bitmap =3D ops->pgsize_bitmap; if (!domain->ops) - domain->ops =3D bus->iommu_ops->default_domain_ops; + domain->ops =3D ops->default_domain_ops; =20 if (iommu_is_dma_domain(domain) && iommu_get_dma_cookie(domain)) { iommu_domain_free(domain); @@ -2128,6 +2130,9 @@ static int iommu_group_do_attach_device(struct device= *dev, void *data) { struct iommu_domain *domain =3D data; =20 + if (dev_iommu_ops(dev) !=3D domain->owner) + return -EINVAL; + return __iommu_attach_device(domain, dev); } =20 diff --git a/include/linux/iommu.h b/include/linux/iommu.h index d37bf28faf82..35af9d4e3969 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -95,6 +95,7 @@ struct iommu_domain_geometry { struct iommu_domain { unsigned type; const struct iommu_domain_ops *ops; + const struct iommu_ops *owner; /* Whose domain_alloc we came from */ unsigned long pgsize_bitmap; /* Bitmap of page sizes in use */ struct iommu_domain_geometry geometry; struct iommu_dma_cookie *iova_cookie; --=20 2.36.1.dirty From nobody Sun Sep 14 16:23:34 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 1D73BC6379F for ; Thu, 19 Jan 2023 19:20:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231455AbjASTUe (ORCPT ); Thu, 19 Jan 2023 14:20:34 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60834 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230401AbjASTUH (ORCPT ); Thu, 19 Jan 2023 14:20:07 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 2A9E69F3B6 for ; Thu, 19 Jan 2023 11:19:16 -0800 (PST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id AB47E1BCA; Thu, 19 Jan 2023 11:19:25 -0800 (PST) Received: from e121345-lin.cambridge.arm.com (e121345-lin.cambridge.arm.com [10.1.196.40]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 434B13F67D; Thu, 19 Jan 2023 11:18:43 -0800 (PST) From: Robin Murphy To: joro@8bytes.org, will@kernel.org Cc: hch@lst.de, jgg@nvidia.com, iommu@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH 3/8] iommu: Factor out a "first device in group" helper Date: Thu, 19 Jan 2023 19:18:21 +0000 Message-Id: <592bff75a7fc4d50d5b2435a09dfff19f1072973.1673978700.git.robin.murphy@arm.com> X-Mailer: git-send-email 2.36.1.dirty In-Reply-To: References: 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" This pattern for picking the first device out of the group list is repeated a few times now, so it's clearly worth factoring out. Signed-off-by: Robin Murphy --- drivers/iommu/iommu.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index bc53ffbba4de..5b37766a09e2 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -1084,6 +1084,11 @@ void iommu_group_remove_device(struct device *dev) } EXPORT_SYMBOL_GPL(iommu_group_remove_device); =20 +static struct device *iommu_group_first_dev(struct iommu_group *group) +{ + return list_first_entry(&group->devices, struct group_device, list)->dev; +} + static int iommu_group_device_count(struct iommu_group *group) { struct group_device *entry; @@ -2835,7 +2840,6 @@ static int iommu_change_dev_def_domain(struct iommu_g= roup *group, struct device *prev_dev, int type) { struct iommu_domain *prev_dom; - struct group_device *grp_dev; int ret, dev_def_dom; struct device *dev; =20 @@ -2867,8 +2871,7 @@ static int iommu_change_dev_def_domain(struct iommu_g= roup *group, } =20 /* Since group has only one device */ - grp_dev =3D list_first_entry(&group->devices, struct group_device, list); - dev =3D grp_dev->dev; + dev =3D iommu_group_first_dev(group); =20 if (prev_dev !=3D dev) { dev_err_ratelimited(prev_dev, "Cannot change default domain: Device has = been changed\n"); @@ -2965,7 +2968,6 @@ static int iommu_change_dev_def_domain(struct iommu_g= roup *group, static ssize_t iommu_group_store_type(struct iommu_group *group, const char *buf, size_t count) { - struct group_device *grp_dev; struct device *dev; int ret, req_type; =20 @@ -3000,8 +3002,7 @@ static ssize_t iommu_group_store_type(struct iommu_gr= oup *group, } =20 /* Since group has only one device */ - grp_dev =3D list_first_entry(&group->devices, struct group_device, list); - dev =3D grp_dev->dev; + dev =3D iommu_group_first_dev(group); get_device(dev); =20 /* @@ -3126,21 +3127,18 @@ void iommu_device_unuse_default_domain(struct devic= e *dev) =20 static int __iommu_group_alloc_blocking_domain(struct iommu_group *group) { - struct group_device *dev =3D - list_first_entry(&group->devices, struct group_device, list); + struct device *dev =3D iommu_group_first_dev(group); =20 if (group->blocking_domain) return 0; =20 - group->blocking_domain =3D - __iommu_domain_alloc(dev->dev->bus, IOMMU_DOMAIN_BLOCKED); + group->blocking_domain =3D __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_BL= OCKED); if (!group->blocking_domain) { /* * For drivers that do not yet understand IOMMU_DOMAIN_BLOCKED * create an empty domain instead. */ - group->blocking_domain =3D __iommu_domain_alloc( - dev->dev->bus, IOMMU_DOMAIN_UNMANAGED); + group->blocking_domain =3D __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_U= NMANAGED); if (!group->blocking_domain) return -EINVAL; } --=20 2.36.1.dirty From nobody Sun Sep 14 16:23:34 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 DA97DC46467 for ; Thu, 19 Jan 2023 19:20:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230336AbjASTUb (ORCPT ); Thu, 19 Jan 2023 14:20:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34172 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231597AbjASTUF (ORCPT ); Thu, 19 Jan 2023 14:20:05 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 376A89EE12 for ; Thu, 19 Jan 2023 11:19:12 -0800 (PST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id BF9001BCB; Thu, 19 Jan 2023 11:19:26 -0800 (PST) Received: from e121345-lin.cambridge.arm.com (e121345-lin.cambridge.arm.com [10.1.196.40]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 5AAC73F67D; Thu, 19 Jan 2023 11:18:44 -0800 (PST) From: Robin Murphy To: joro@8bytes.org, will@kernel.org Cc: hch@lst.de, jgg@nvidia.com, iommu@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH 4/8] iommu: Switch __iommu_domain_alloc() to device ops Date: Thu, 19 Jan 2023 19:18:22 +0000 Message-Id: <25ea8128b9228f9893507ad5a764ff25db5961a0.1673978700.git.robin.murphy@arm.com> X-Mailer: git-send-email 2.36.1.dirty In-Reply-To: References: 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 all the places we allocate default domains, we have (or can easily get hold of) a device from which to resolve the right IOMMU ops; only the public iommu_domain_alloc() interface actually depends on bus ops. Reworking the public API is a big enough mission in its own right, but in the meantime we can still decouple it from bus ops internally to move forward. Signed-off-by: Robin Murphy --- drivers/iommu/iommu.c | 57 ++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 5b37766a09e2..1a31d94adff5 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -88,7 +88,7 @@ static int iommu_bus_notifier(struct notifier_block *nb, unsigned long action, void *data); static int iommu_alloc_default_domain(struct iommu_group *group, struct device *dev); -static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus, +static struct iommu_domain *__iommu_domain_alloc(struct device *dev, unsigned type); static int __iommu_attach_device(struct iommu_domain *domain, struct device *dev); @@ -1620,15 +1620,15 @@ static int iommu_get_def_domain_type(struct device = *dev) return 0; } =20 -static int iommu_group_alloc_default_domain(struct bus_type *bus, - struct iommu_group *group, +static int iommu_group_alloc_default_domain(struct iommu_group *group, + struct device *dev, unsigned int type) { struct iommu_domain *dom; =20 - dom =3D __iommu_domain_alloc(bus, type); + dom =3D __iommu_domain_alloc(dev, type); if (!dom && type !=3D IOMMU_DOMAIN_DMA) { - dom =3D __iommu_domain_alloc(bus, IOMMU_DOMAIN_DMA); + dom =3D __iommu_domain_alloc(dev, IOMMU_DOMAIN_DMA); if (dom) pr_warn("Failed to allocate default IOMMU domain of type %u for group %= s - Falling back to IOMMU_DOMAIN_DMA", type, group->name); @@ -1653,7 +1653,7 @@ static int iommu_alloc_default_domain(struct iommu_gr= oup *group, =20 type =3D iommu_get_def_domain_type(dev) ? : iommu_def_domain_type; =20 - return iommu_group_alloc_default_domain(dev->bus, group, type); + return iommu_group_alloc_default_domain(group, dev, type); } =20 /** @@ -1766,8 +1766,7 @@ static int probe_get_default_domain_type(struct devic= e *dev, void *data) return 0; } =20 -static void probe_alloc_default_domain(struct bus_type *bus, - struct iommu_group *group) +static void probe_alloc_default_domain(struct iommu_group *group) { struct __group_domain_type gtype; =20 @@ -1777,10 +1776,12 @@ static void probe_alloc_default_domain(struct bus_t= ype *bus, __iommu_group_for_each_dev(group, >ype, probe_get_default_domain_type); =20 - if (!gtype.type) + if (!gtype.type) { gtype.type =3D iommu_def_domain_type; + gtype.dev =3D iommu_group_first_dev(group); + } =20 - iommu_group_alloc_default_domain(bus, group, gtype.type); + iommu_group_alloc_default_domain(group, gtype.dev, gtype.type); =20 } =20 @@ -1854,7 +1855,7 @@ int bus_iommu_probe(struct bus_type *bus) list_del_init(&group->entry); =20 /* Try to allocate default domain */ - probe_alloc_default_domain(bus, group); + probe_alloc_default_domain(group); =20 if (!group->default_domain) { mutex_unlock(&group->mutex); @@ -1943,15 +1944,12 @@ void iommu_set_fault_handler(struct iommu_domain *d= omain, } EXPORT_SYMBOL_GPL(iommu_set_fault_handler); =20 -static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus, +static struct iommu_domain *__iommu_domain_alloc(struct device *dev, unsigned type) { - const struct iommu_ops *ops =3D bus ? bus->iommu_ops : NULL; + const struct iommu_ops *ops =3D dev_iommu_ops(dev); struct iommu_domain *domain; =20 - if (!ops) - return NULL; - domain =3D ops->domain_alloc(type); if (!domain) return NULL; @@ -1970,9 +1968,28 @@ static struct iommu_domain *__iommu_domain_alloc(str= uct bus_type *bus, return domain; } =20 +static int __iommu_domain_alloc_dev(struct device *dev, void *data) +{ + struct device **alloc_dev =3D data; + + if (!device_iommu_mapped(dev)) + return 0; + + WARN_ONCE(*alloc_dev && dev_iommu_ops(dev) !=3D dev_iommu_ops(*alloc_dev), + "Multiple IOMMU drivers present, which the public IOMMU API can't fully = support yet. This may not work as expected, sorry!\n"); + + *alloc_dev =3D dev; + return 0; +} + struct iommu_domain *iommu_domain_alloc(struct bus_type *bus) { - return __iommu_domain_alloc(bus, IOMMU_DOMAIN_UNMANAGED); + struct device *dev =3D NULL; + + if (bus_for_each_dev(bus, NULL, &dev, __iommu_domain_alloc_dev)) + return NULL; + + return __iommu_domain_alloc(dev, IOMMU_DOMAIN_UNMANAGED); } EXPORT_SYMBOL_GPL(iommu_domain_alloc); =20 @@ -2918,7 +2935,7 @@ static int iommu_change_dev_def_domain(struct iommu_g= roup *group, } =20 /* Sets group->default_domain to the newly allocated domain */ - ret =3D iommu_group_alloc_default_domain(dev->bus, group, type); + ret =3D iommu_group_alloc_default_domain(group, dev, type); if (ret) goto out; =20 @@ -3132,13 +3149,13 @@ static int __iommu_group_alloc_blocking_domain(stru= ct iommu_group *group) if (group->blocking_domain) return 0; =20 - group->blocking_domain =3D __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_BL= OCKED); + group->blocking_domain =3D __iommu_domain_alloc(dev, IOMMU_DOMAIN_BLOCKED= ); if (!group->blocking_domain) { /* * For drivers that do not yet understand IOMMU_DOMAIN_BLOCKED * create an empty domain instead. */ - group->blocking_domain =3D __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_U= NMANAGED); + group->blocking_domain =3D __iommu_domain_alloc(dev, IOMMU_DOMAIN_UNMANA= GED); if (!group->blocking_domain) return -EINVAL; } --=20 2.36.1.dirty From nobody Sun Sep 14 16:23:34 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 E4A9AC6379F for ; Thu, 19 Jan 2023 19:20:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231439AbjASTU6 (ORCPT ); Thu, 19 Jan 2023 14:20:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60842 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231447AbjASTUd (ORCPT ); Thu, 19 Jan 2023 14:20:33 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id CEC6446726 for ; Thu, 19 Jan 2023 11:19:44 -0800 (PST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E02CC106F; Thu, 19 Jan 2023 11:19:27 -0800 (PST) Received: from e121345-lin.cambridge.arm.com (e121345-lin.cambridge.arm.com [10.1.196.40]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 71A913F67D; Thu, 19 Jan 2023 11:18:45 -0800 (PST) From: Robin Murphy To: joro@8bytes.org, will@kernel.org Cc: hch@lst.de, jgg@nvidia.com, iommu@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH 5/8] iommu/arm-smmu: Don't register fwnode for legacy binding Date: Thu, 19 Jan 2023 19:18:23 +0000 Message-Id: <01c68ef4d924d3671016690fa946eab306a1de07.1673978700.git.robin.murphy@arm.com> X-Mailer: git-send-email 2.36.1.dirty In-Reply-To: References: 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" When using the legacy binding we bypass the of_xlate mechanism, so avoid registering the instance fwnodes which act as keys for that. This will help __iommu_probe_device() to retrieve the registered ops the same way as for x86 etc. when no fwspec has previously been set up by of_xlate. Signed-off-by: Robin Murphy --- drivers/iommu/arm/arm-smmu/arm-smmu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-= smmu/arm-smmu.c index 719fbca1fe52..607f06af01b6 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -2156,7 +2156,8 @@ static int arm_smmu_device_probe(struct platform_devi= ce *pdev) return err; } =20 - err =3D iommu_device_register(&smmu->iommu, &arm_smmu_ops, dev); + err =3D iommu_device_register(&smmu->iommu, &arm_smmu_ops, + using_legacy_binding ? NULL : dev); if (err) { dev_err(dev, "Failed to register iommu\n"); iommu_device_sysfs_remove(&smmu->iommu); --=20 2.36.1.dirty From nobody Sun Sep 14 16:23:34 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 569CDC678D4 for ; Thu, 19 Jan 2023 19:21:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230179AbjASTVA (ORCPT ); Thu, 19 Jan 2023 14:21:00 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60836 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231450AbjASTUd (ORCPT ); Thu, 19 Jan 2023 14:20:33 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 0584E5B581 for ; Thu, 19 Jan 2023 11:19:44 -0800 (PST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id D5E561BF3; Thu, 19 Jan 2023 11:19:30 -0800 (PST) Received: from e121345-lin.cambridge.arm.com (e121345-lin.cambridge.arm.com [10.1.196.40]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 39BD23F67D; Thu, 19 Jan 2023 11:18:48 -0800 (PST) From: Robin Murphy To: joro@8bytes.org, will@kernel.org Cc: hch@lst.de, jgg@nvidia.com, iommu@lists.linux.dev, linux-kernel@vger.kernel.org, "Rafael J . Wysocki" , Greg Kroah-Hartman Subject: [PATCH 6/8] iommu: Retire bus ops Date: Thu, 19 Jan 2023 19:18:24 +0000 Message-Id: X-Mailer: git-send-email 2.36.1.dirty In-Reply-To: References: 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" With the rest of the API internals converted, it's time to finally tackle probe_device and how we bootstrap the per-device ops association to begin with. This ends up being disappointingly straightforward, since fwspec users are already doing it in order to find their of_xlate callback, and it works out that we can easily do the equivalent for other drivers too. Then shuffle the remaining awareness of iommu_ops into the couple of core headers that still need it, and breathe a sigh of relief... Ding dong the bus ops are gone! CC: Rafael J. Wysocki CC: Greg Kroah-Hartman CC: Christoph Hellwig Signed-off-by: Robin Murphy Acked-by: Greg Kroah-Hartman --- drivers/iommu/iommu.c | 27 ++++++++++++++++----------- include/acpi/acpi_bus.h | 2 ++ include/linux/device.h | 1 - include/linux/device/bus.h | 5 ----- include/linux/dma-map-ops.h | 1 + 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 1a31d94adff5..8997b8f2e79f 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -218,13 +218,6 @@ int iommu_device_register(struct iommu_device *iommu, /* We need to be able to take module references appropriately */ if (WARN_ON(is_module_address((unsigned long)ops) && !ops->owner)) return -EINVAL; - /* - * Temporarily enforce global restriction to a single driver. This was - * already the de-facto behaviour, since any possible combination of - * existing drivers would compete for at least the PCI or platform bus. - */ - if (iommu_buses[0]->iommu_ops && iommu_buses[0]->iommu_ops !=3D ops) - return -EBUSY; =20 iommu->ops =3D ops; if (hwdev) @@ -234,10 +227,8 @@ int iommu_device_register(struct iommu_device *iommu, list_add_tail(&iommu->list, &iommu_device_list); spin_unlock(&iommu_device_lock); =20 - for (int i =3D 0; i < ARRAY_SIZE(iommu_buses) && !err; i++) { - iommu_buses[i]->iommu_ops =3D ops; + for (int i =3D 0; i < ARRAY_SIZE(iommu_buses) && !err; i++) err =3D bus_iommu_probe(iommu_buses[i]); - } if (err) iommu_device_unregister(iommu); return err; @@ -303,12 +294,26 @@ static u32 dev_iommu_get_max_pasids(struct device *de= v) =20 static int __iommu_probe_device(struct device *dev, struct list_head *grou= p_list) { - const struct iommu_ops *ops =3D dev->bus->iommu_ops; + const struct iommu_ops *ops; struct iommu_device *iommu_dev; + struct iommu_fwspec *fwspec; struct iommu_group *group; static DEFINE_MUTEX(iommu_probe_device_lock); int ret; =20 + /* + * For FDT-based systems and ACPI IORT/VIOT, drivers register IOMMU + * instances with non-NULL fwnodes, and client devices should have been + * identified with a fwspec by this point. For Intel/AMD/s390/PAMU we + * can assume a single active driver with global ops, and so grab those + * from any registered instance, cheekily co-opting the same mechanism. + */ + fwspec =3D dev_iommu_fwspec_get(dev); + if (fwspec && fwspec->ops) + ops =3D fwspec->ops; + else + ops =3D iommu_ops_from_fwnode(NULL); + if (!ops) return -ENODEV; /* diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index cd3b75e08ec3..067dde9291c9 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -614,6 +614,8 @@ struct acpi_pci_root { =20 /* helper */ =20 +struct iommu_ops; + bool acpi_dma_supported(const struct acpi_device *adev); enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev); int acpi_iommu_fwspec_init(struct device *dev, u32 id, diff --git a/include/linux/device.h b/include/linux/device.h index 44e3acae7b36..f7a7ecafedd3 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -41,7 +41,6 @@ struct class; struct subsys_private; struct device_node; struct fwnode_handle; -struct iommu_ops; struct iommu_group; struct dev_pin_info; struct dev_iommu; diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h index d8b29ccd07e5..4ece3470112f 100644 --- a/include/linux/device/bus.h +++ b/include/linux/device/bus.h @@ -63,9 +63,6 @@ struct fwnode_handle; * this bus. * @pm: Power management operations of this bus, callback the specific * device driver's pm-ops. - * @iommu_ops: IOMMU specific operations for this bus, used to attach IOM= MU - * driver implementations to a bus and allow the driver to do - * bus-specific setup * @p: The private data of the driver core, only the driver core can * touch this. * @lock_key: Lock class key for use by the lock validator @@ -109,8 +106,6 @@ struct bus_type { =20 const struct dev_pm_ops *pm; =20 - const struct iommu_ops *iommu_ops; - struct subsys_private *p; struct lock_class_key lock_key; =20 diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h index d678afeb8a13..e8ebf0bf611b 100644 --- a/include/linux/dma-map-ops.h +++ b/include/linux/dma-map-ops.h @@ -10,6 +10,7 @@ #include =20 struct cma; +struct iommu_ops; =20 /* * Values for struct dma_map_ops.flags: --=20 2.36.1.dirty From nobody Sun Sep 14 16:23:34 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 B369FC004D4 for ; Thu, 19 Jan 2023 19:21:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231262AbjASTVM (ORCPT ); Thu, 19 Jan 2023 14:21:12 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33346 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231146AbjASTUo (ORCPT ); Thu, 19 Jan 2023 14:20:44 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id C943C9AAA4 for ; Thu, 19 Jan 2023 11:19:46 -0800 (PST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id EC1101BF7; Thu, 19 Jan 2023 11:19:31 -0800 (PST) Received: from e121345-lin.cambridge.arm.com (e121345-lin.cambridge.arm.com [10.1.196.40]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 8795C3F67D; Thu, 19 Jan 2023 11:18:49 -0800 (PST) From: Robin Murphy To: joro@8bytes.org, will@kernel.org Cc: hch@lst.de, jgg@nvidia.com, iommu@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH 7/8] iommu: Clean up open-coded ownership checks Date: Thu, 19 Jan 2023 19:18:25 +0000 Message-Id: <47109befd7a32d03bffe54192bf02f8c8a223858.1673978700.git.robin.murphy@arm.com> X-Mailer: git-send-email 2.36.1.dirty In-Reply-To: References: 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" Some drivers already implement their own defence against the possibility of being given someone else's device. Since this is now taken care of by the core code (and via a slightly different path from the original fwspec-based idea), let's clean them up. Signed-off-by: Robin Murphy --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 3 --- drivers/iommu/arm/arm-smmu/arm-smmu.c | 9 +-------- drivers/iommu/arm/arm-smmu/qcom_iommu.c | 16 +++------------- drivers/iommu/mtk_iommu.c | 7 +------ drivers/iommu/mtk_iommu_v1.c | 3 --- drivers/iommu/sprd-iommu.c | 8 +------- drivers/iommu/virtio-iommu.c | 3 --- 7 files changed, 6 insertions(+), 43 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/ar= m/arm-smmu-v3/arm-smmu-v3.c index ab160198edd6..cb05d9771192 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -2642,9 +2642,6 @@ static struct iommu_device *arm_smmu_probe_device(str= uct device *dev) struct arm_smmu_master *master; struct iommu_fwspec *fwspec =3D dev_iommu_fwspec_get(dev); =20 - if (!fwspec || fwspec->ops !=3D &arm_smmu_ops) - return ERR_PTR(-ENODEV); - if (WARN_ON_ONCE(dev_iommu_priv_get(dev))) return ERR_PTR(-EBUSY); =20 diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-= smmu/arm-smmu.c index 607f06af01b6..235550db0d59 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -1118,11 +1118,6 @@ static int arm_smmu_attach_dev(struct iommu_domain *= domain, struct device *dev) struct arm_smmu_device *smmu; int ret; =20 - if (!fwspec || fwspec->ops !=3D &arm_smmu_ops) { - dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n"); - return -ENXIO; - } - /* * FIXME: The arch/arm DMA API code tries to attach devices to its own * domains between of_xlate() and probe_device() - we have no way to cope @@ -1352,10 +1347,8 @@ static struct iommu_device *arm_smmu_probe_device(st= ruct device *dev) fwspec =3D dev_iommu_fwspec_get(dev); if (ret) goto out_free; - } else if (fwspec && fwspec->ops =3D=3D &arm_smmu_ops) { - smmu =3D arm_smmu_get_by_fwnode(fwspec->iommu_fwnode); } else { - return ERR_PTR(-ENODEV); + smmu =3D arm_smmu_get_by_fwnode(fwspec->iommu_fwnode); } =20 ret =3D -EINVAL; diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/ar= m-smmu/qcom_iommu.c index 270c3d9128ba..b2d3d309be1e 100644 --- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c +++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c @@ -79,16 +79,6 @@ static struct qcom_iommu_domain *to_qcom_iommu_domain(st= ruct iommu_domain *dom) =20 static const struct iommu_ops qcom_iommu_ops; =20 -static struct qcom_iommu_dev * to_iommu(struct device *dev) -{ - struct iommu_fwspec *fwspec =3D dev_iommu_fwspec_get(dev); - - if (!fwspec || fwspec->ops !=3D &qcom_iommu_ops) - return NULL; - - return dev_iommu_priv_get(dev); -} - static struct qcom_iommu_ctx * to_ctx(struct qcom_iommu_domain *d, unsigne= d asid) { struct qcom_iommu_dev *qcom_iommu =3D d->iommu; @@ -361,7 +351,7 @@ static void qcom_iommu_domain_free(struct iommu_domain = *domain) =20 static int qcom_iommu_attach_dev(struct iommu_domain *domain, struct devic= e *dev) { - struct qcom_iommu_dev *qcom_iommu =3D to_iommu(dev); + struct qcom_iommu_dev *qcom_iommu =3D dev_iommu_priv_get(dev); struct qcom_iommu_domain *qcom_domain =3D to_qcom_iommu_domain(domain); int ret; =20 @@ -391,7 +381,7 @@ static void qcom_iommu_detach_dev(struct iommu_domain *= domain, struct device *de { struct qcom_iommu_domain *qcom_domain =3D to_qcom_iommu_domain(domain); struct iommu_fwspec *fwspec =3D dev_iommu_fwspec_get(dev); - struct qcom_iommu_dev *qcom_iommu =3D to_iommu(dev); + struct qcom_iommu_dev *qcom_iommu =3D dev_iommu_priv_get(dev); unsigned i; =20 if (WARN_ON(!qcom_domain->iommu)) @@ -508,7 +498,7 @@ static bool qcom_iommu_capable(struct device *dev, enum= iommu_cap cap) =20 static struct iommu_device *qcom_iommu_probe_device(struct device *dev) { - struct qcom_iommu_dev *qcom_iommu =3D to_iommu(dev); + struct qcom_iommu_dev *qcom_iommu =3D dev_iommu_priv_get(dev); struct device_link *link; =20 if (!qcom_iommu) diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 2badd6acfb23..005136a4cc36 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -784,16 +784,11 @@ static phys_addr_t mtk_iommu_iova_to_phys(struct iomm= u_domain *domain, static struct iommu_device *mtk_iommu_probe_device(struct device *dev) { struct iommu_fwspec *fwspec =3D dev_iommu_fwspec_get(dev); - struct mtk_iommu_data *data; + struct mtk_iommu_data *data =3D dev_iommu_priv_get(dev); struct device_link *link; struct device *larbdev; unsigned int larbid, larbidx, i; =20 - if (!fwspec || fwspec->ops !=3D &mtk_iommu_ops) - return ERR_PTR(-ENODEV); /* Not a iommu client device */ - - data =3D dev_iommu_priv_get(dev); - if (!MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) return &data->iommu; =20 diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index 69682ee068d2..dff8ea0af884 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -478,9 +478,6 @@ static struct iommu_device *mtk_iommu_v1_probe_device(s= truct device *dev) idx++; } =20 - if (!fwspec || fwspec->ops !=3D &mtk_iommu_v1_ops) - return ERR_PTR(-ENODEV); /* Not a iommu client device */ - data =3D dev_iommu_priv_get(dev); =20 /* Link the consumer device with the smi-larb device(supplier) */ diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c index 219bfa11f7f4..4cebccb6fc8b 100644 --- a/drivers/iommu/sprd-iommu.c +++ b/drivers/iommu/sprd-iommu.c @@ -373,13 +373,7 @@ static phys_addr_t sprd_iommu_iova_to_phys(struct iomm= u_domain *domain, =20 static struct iommu_device *sprd_iommu_probe_device(struct device *dev) { - struct iommu_fwspec *fwspec =3D dev_iommu_fwspec_get(dev); - struct sprd_iommu_device *sdev; - - if (!fwspec || fwspec->ops !=3D &sprd_iommu_ops) - return ERR_PTR(-ENODEV); - - sdev =3D dev_iommu_priv_get(dev); + struct sprd_iommu_device *sdev =3D dev_iommu_priv_get(dev); =20 return &sdev->iommu; } diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c index 5b8fe9bfa9a5..59f1abd6ee53 100644 --- a/drivers/iommu/virtio-iommu.c +++ b/drivers/iommu/virtio-iommu.c @@ -945,9 +945,6 @@ static struct iommu_device *viommu_probe_device(struct = device *dev) struct viommu_dev *viommu =3D NULL; struct iommu_fwspec *fwspec =3D dev_iommu_fwspec_get(dev); =20 - if (!fwspec || fwspec->ops !=3D &viommu_ops) - return ERR_PTR(-ENODEV); - viommu =3D viommu_get_by_fwnode(fwspec->iommu_fwnode); if (!viommu) return ERR_PTR(-ENODEV); --=20 2.36.1.dirty From nobody Sun Sep 14 16:23:34 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 0EBA6C6379F for ; Thu, 19 Jan 2023 19:21:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231304AbjASTVO (ORCPT ); Thu, 19 Jan 2023 14:21:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33316 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231154AbjASTUo (ORCPT ); Thu, 19 Jan 2023 14:20:44 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id BE63F966F7 for ; Thu, 19 Jan 2023 11:19:46 -0800 (PST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0E3611C00; Thu, 19 Jan 2023 11:19:33 -0800 (PST) Received: from e121345-lin.cambridge.arm.com (e121345-lin.cambridge.arm.com [10.1.196.40]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 9E1103F67D; Thu, 19 Jan 2023 11:18:50 -0800 (PST) From: Robin Murphy To: joro@8bytes.org, will@kernel.org Cc: hch@lst.de, jgg@nvidia.com, iommu@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH 8/8] iommu: Pass device through ops->domain_alloc Date: Thu, 19 Jan 2023 19:18:26 +0000 Message-Id: <893b2ef069fad5276d015a7606c01a0da315f9da.1673978700.git.robin.murphy@arm.com> X-Mailer: git-send-email 2.36.1.dirty In-Reply-To: References: 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" With __iommu_domain_alloc() now aware of a device, we can propagate that through to the drivers so that they can also pick up their instance data without having to wait until they see the device attach. Signed-off-by: Robin Murphy --- drivers/iommu/amd/iommu.c | 3 ++- drivers/iommu/apple-dart.c | 3 ++- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 3 ++- drivers/iommu/arm/arm-smmu/arm-smmu.c | 3 ++- drivers/iommu/arm/arm-smmu/qcom_iommu.c | 3 ++- drivers/iommu/exynos-iommu.c | 3 ++- drivers/iommu/fsl_pamu_domain.c | 3 ++- drivers/iommu/intel/iommu.c | 3 ++- drivers/iommu/iommu.c | 4 ++-- drivers/iommu/ipmmu-vmsa.c | 3 ++- drivers/iommu/msm_iommu.c | 3 ++- drivers/iommu/mtk_iommu.c | 3 ++- drivers/iommu/mtk_iommu_v1.c | 3 ++- drivers/iommu/omap-iommu.c | 3 ++- drivers/iommu/rockchip-iommu.c | 3 ++- drivers/iommu/s390-iommu.c | 3 ++- drivers/iommu/sprd-iommu.c | 3 ++- drivers/iommu/sun50i-iommu.c | 3 ++- drivers/iommu/tegra-gart.c | 3 ++- drivers/iommu/tegra-smmu.c | 3 ++- drivers/iommu/virtio-iommu.c | 3 ++- include/linux/iommu.h | 3 ++- 22 files changed, 44 insertions(+), 23 deletions(-) diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index cbeaab55c0db..f5bc61a4c3d4 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -2084,7 +2084,8 @@ static struct protection_domain *protection_domain_al= loc(unsigned int type) return NULL; } =20 -static struct iommu_domain *amd_iommu_domain_alloc(unsigned type) +static struct iommu_domain *amd_iommu_domain_alloc(struct device *dev, + unsigned type) { struct protection_domain *domain; =20 diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c index 4f4a323be0d0..95f3aa323a99 100644 --- a/drivers/iommu/apple-dart.c +++ b/drivers/iommu/apple-dart.c @@ -576,7 +576,8 @@ static void apple_dart_release_device(struct device *de= v) kfree(cfg); } =20 -static struct iommu_domain *apple_dart_domain_alloc(unsigned int type) +static struct iommu_domain *apple_dart_domain_alloc(struct device *dev, + unsigned int type) { struct apple_dart_domain *dart_domain; =20 diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/ar= m/arm-smmu-v3/arm-smmu-v3.c index cb05d9771192..453e9dbf4920 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -2005,7 +2005,8 @@ static bool arm_smmu_capable(struct device *dev, enum= iommu_cap cap) } } =20 -static struct iommu_domain *arm_smmu_domain_alloc(unsigned type) +static struct iommu_domain *arm_smmu_domain_alloc(struct device *dev, + unsigned type) { struct arm_smmu_domain *smmu_domain; =20 diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-= smmu/arm-smmu.c index 235550db0d59..86c9c6df18ae 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -851,7 +851,8 @@ static void arm_smmu_destroy_domain_context(struct iomm= u_domain *domain) arm_smmu_rpm_put(smmu); } =20 -static struct iommu_domain *arm_smmu_domain_alloc(unsigned type) +static struct iommu_domain *arm_smmu_domain_alloc(struct device *dev, + unsigned type) { struct arm_smmu_domain *smmu_domain; =20 diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/ar= m-smmu/qcom_iommu.c index b2d3d309be1e..7b9daacf1697 100644 --- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c +++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c @@ -309,7 +309,8 @@ static int qcom_iommu_init_domain(struct iommu_domain *= domain, return ret; } =20 -static struct iommu_domain *qcom_iommu_domain_alloc(unsigned type) +static struct iommu_domain *qcom_iommu_domain_alloc(struct device *dev, + unsigned type) { struct qcom_iommu_domain *qcom_domain; =20 diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index b0cde2211987..54f9d10a9fb1 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -816,7 +816,8 @@ static inline void exynos_iommu_set_pte(sysmmu_pte_t *e= nt, sysmmu_pte_t val) DMA_TO_DEVICE); } =20 -static struct iommu_domain *exynos_iommu_domain_alloc(unsigned type) +static struct iommu_domain *exynos_iommu_domain_alloc(struct device *dev, + unsigned type) { struct exynos_iommu_domain *domain; dma_addr_t handle; diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domai= n.c index 4408ac3c49b6..69578e574af0 100644 --- a/drivers/iommu/fsl_pamu_domain.c +++ b/drivers/iommu/fsl_pamu_domain.c @@ -192,7 +192,8 @@ static void fsl_pamu_domain_free(struct iommu_domain *d= omain) kmem_cache_free(fsl_pamu_domain_cache, dma_domain); } =20 -static struct iommu_domain *fsl_pamu_domain_alloc(unsigned type) +static struct iommu_domain *fsl_pamu_domain_alloc(struct device *dev, + unsigned type) { struct fsl_dma_domain *dma_domain; =20 diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 59df7e42fd53..590594a0d6e1 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -4157,7 +4157,8 @@ static struct iommu_domain blocking_domain =3D { } }; =20 -static struct iommu_domain *intel_iommu_domain_alloc(unsigned type) +static struct iommu_domain *intel_iommu_domain_alloc(struct device *dev, + unsigned type) { struct dmar_domain *dmar_domain; struct iommu_domain *domain; diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 8997b8f2e79f..521f6f780294 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -1955,7 +1955,7 @@ static struct iommu_domain *__iommu_domain_alloc(stru= ct device *dev, const struct iommu_ops *ops =3D dev_iommu_ops(dev); struct iommu_domain *domain; =20 - domain =3D ops->domain_alloc(type); + domain =3D ops->domain_alloc(dev, type); if (!domain) return NULL; =20 @@ -3456,7 +3456,7 @@ struct iommu_domain *iommu_sva_domain_alloc(struct de= vice *dev, const struct iommu_ops *ops =3D dev_iommu_ops(dev); struct iommu_domain *domain; =20 - domain =3D ops->domain_alloc(IOMMU_DOMAIN_SVA); + domain =3D ops->domain_alloc(dev, IOMMU_DOMAIN_SVA); if (!domain) return NULL; =20 diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index 76e51d8e3732..7bb6c2fd3214 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c @@ -567,7 +567,8 @@ static irqreturn_t ipmmu_irq(int irq, void *dev) * IOMMU Operations */ =20 -static struct iommu_domain *ipmmu_domain_alloc(unsigned type) +static struct iommu_domain *ipmmu_domain_alloc(struct device *dev, + unsigned type) { struct ipmmu_vmsa_domain *domain; =20 diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c index c60624910872..1d9704e7c75f 100644 --- a/drivers/iommu/msm_iommu.c +++ b/drivers/iommu/msm_iommu.c @@ -302,7 +302,8 @@ static void __program_context(void __iomem *base, int c= tx, SET_M(base, ctx, 1); } =20 -static struct iommu_domain *msm_iommu_domain_alloc(unsigned type) +static struct iommu_domain *msm_iommu_domain_alloc(struct device *dev, + unsigned type) { struct msm_priv *priv; =20 diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 005136a4cc36..711716c8dcdf 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -632,7 +632,8 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_d= omain *dom, return 0; } =20 -static struct iommu_domain *mtk_iommu_domain_alloc(unsigned type) +static struct iommu_domain *mtk_iommu_domain_alloc(struct device *dev, + unsigned type) { struct mtk_iommu_domain *dom; =20 diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index dff8ea0af884..3d1e0635f9b3 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -270,7 +270,8 @@ static int mtk_iommu_v1_domain_finalise(struct mtk_iomm= u_v1_data *data) return 0; } =20 -static struct iommu_domain *mtk_iommu_v1_domain_alloc(unsigned type) +static struct iommu_domain *mtk_iommu_v1_domain_alloc(struct device *dev, + unsigned type) { struct mtk_iommu_v1_domain *dom; =20 diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index 2fd7702c6709..19a22ba1860d 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c @@ -1566,7 +1566,8 @@ static void omap_iommu_detach_dev(struct iommu_domain= *domain, spin_unlock(&omap_domain->lock); } =20 -static struct iommu_domain *omap_iommu_domain_alloc(unsigned type) +static struct iommu_domain *omap_iommu_domain_alloc(struct device *dev, + unsigned type) { struct omap_iommu_domain *omap_domain; =20 diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index a68eadd64f38..50b17a096ea5 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c @@ -1057,7 +1057,8 @@ static int rk_iommu_attach_device(struct iommu_domain= *domain, return ret; } =20 -static struct iommu_domain *rk_iommu_domain_alloc(unsigned type) +static struct iommu_domain *rk_iommu_domain_alloc(struct device *dev, + unsigned type) { struct rk_iommu_domain *rk_domain; =20 diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c index ed33c6cce083..a56e4e282469 100644 --- a/drivers/iommu/s390-iommu.c +++ b/drivers/iommu/s390-iommu.c @@ -41,7 +41,8 @@ static bool s390_iommu_capable(struct device *dev, enum i= ommu_cap cap) } } =20 -static struct iommu_domain *s390_domain_alloc(unsigned domain_type) +static struct iommu_domain *s390_domain_alloc(struct device *dev, + unsigned domain_type) { struct s390_domain *s390_domain; =20 diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c index 4cebccb6fc8b..32992cb07c4f 100644 --- a/drivers/iommu/sprd-iommu.c +++ b/drivers/iommu/sprd-iommu.c @@ -132,7 +132,8 @@ sprd_iommu_pgt_size(struct iommu_domain *domain) SPRD_IOMMU_PAGE_SHIFT) * sizeof(u32); } =20 -static struct iommu_domain *sprd_iommu_domain_alloc(unsigned int domain_ty= pe) +static struct iommu_domain *sprd_iommu_domain_alloc(struct device *dev, + unsigned int domain_type) { struct sprd_iommu_domain *dom; =20 diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c index 5b585eace3d4..10c7eb9c5f11 100644 --- a/drivers/iommu/sun50i-iommu.c +++ b/drivers/iommu/sun50i-iommu.c @@ -667,7 +667,8 @@ static phys_addr_t sun50i_iommu_iova_to_phys(struct iom= mu_domain *domain, sun50i_iova_get_page_offset(iova); } =20 -static struct iommu_domain *sun50i_iommu_domain_alloc(unsigned type) +static struct iommu_domain *sun50i_iommu_domain_alloc(struct device *dev, + unsigned type) { struct sun50i_iommu_domain *sun50i_domain; =20 diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c index ed53279d1106..75bcf191b091 100644 --- a/drivers/iommu/tegra-gart.c +++ b/drivers/iommu/tegra-gart.c @@ -141,7 +141,8 @@ static void gart_iommu_detach_dev(struct iommu_domain *= domain, spin_unlock(&gart->dom_lock); } =20 -static struct iommu_domain *gart_iommu_domain_alloc(unsigned type) +static struct iommu_domain *gart_iommu_domain_alloc(struct device *dev, + unsigned type) { struct iommu_domain *domain; =20 diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index 5b1af40221ec..c7c34d9f60ec 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c @@ -272,7 +272,8 @@ static void tegra_smmu_free_asid(struct tegra_smmu *smm= u, unsigned int id) clear_bit(id, smmu->asids); } =20 -static struct iommu_domain *tegra_smmu_domain_alloc(unsigned type) +static struct iommu_domain *tegra_smmu_domain_alloc(struct device *dev, + unsigned type) { struct tegra_smmu_as *as; =20 diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c index 59f1abd6ee53..7f397767a8e2 100644 --- a/drivers/iommu/virtio-iommu.c +++ b/drivers/iommu/virtio-iommu.c @@ -637,7 +637,8 @@ static void viommu_event_handler(struct virtqueue *vq) =20 /* IOMMU API */ =20 -static struct iommu_domain *viommu_domain_alloc(unsigned type) +static struct iommu_domain *viommu_domain_alloc(struct device *dev, + unsigned type) { struct viommu_domain *vdomain; =20 diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 35af9d4e3969..3a8930d36046 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -252,7 +252,8 @@ struct iommu_ops { bool (*capable)(struct device *dev, enum iommu_cap); =20 /* Domain allocation and freeing by the iommu driver */ - struct iommu_domain *(*domain_alloc)(unsigned iommu_domain_type); + struct iommu_domain *(*domain_alloc)(struct device *dev, + unsigned iommu_domain_type); =20 struct iommu_device *(*probe_device)(struct device *dev); void (*release_device)(struct device *dev); --=20 2.36.1.dirty