From nobody Mon Jan 5 11:16:56 2026 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 8C3EDE7849A for ; Mon, 2 Oct 2023 13:49:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237506AbjJBNt2 (ORCPT ); Mon, 2 Oct 2023 09:49:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45148 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237515AbjJBNt0 (ORCPT ); Mon, 2 Oct 2023 09:49:26 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 774BCB0 for ; Mon, 2 Oct 2023 06:49:23 -0700 (PDT) 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 AF49BDA7; Mon, 2 Oct 2023 06:50:01 -0700 (PDT) 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 658D23F762; Mon, 2 Oct 2023 06:49:22 -0700 (PDT) From: Robin Murphy To: joro@8bytes.org, will@kernel.org Cc: iommu@lists.linux.dev, jgg@nvidia.com, baolu.lu@linux.intel.com, linux-kernel@vger.kernel.org Subject: [PATCH v4 1/7] iommu: Factor out some helpers Date: Mon, 2 Oct 2023 14:49:09 +0100 Message-Id: X-Mailer: git-send-email 2.39.2.101.g768bb238c484.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" The pattern for picking the first device out of the group list is repeated a few times now, so it's clearly worth factoring out, which also helps hide the iommu_group_dev detail from places that don't need to know. Similarly, the safety check for dev_iommu_ops() at certain public interfaces starts looking a bit repetitive, and might not be completely obvious at first glance, so let's factor that out for clarity as well, in preparation for more uses of both. Reviewed-by: Lu Baolu Signed-off-by: Robin Murphy --- v3: Rename dev_iommu_ops_valid() to reflect what it's actually checking, rather than an implied consequence. v4: Rebase, also catch the sneaky one in iommu_get_group_resv_regions() which wasn't the full pattern (but really should be since it guards the dev_iommu_ops() invocation in iommu_get_resv_regions()). --- drivers/iommu/iommu.c | 56 ++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 1ecac2b5c54f..f7793d1b5c3e 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -368,6 +368,15 @@ static void dev_iommu_free(struct device *dev) kfree(param); } =20 +/* + * Internal equivalent of device_iommu_mapped() for when we care that a de= vice + * actually has API ops, and don't want false positives from VFIO-only gro= ups. + */ +static bool dev_has_iommu(struct device *dev) +{ + return dev->iommu && dev->iommu->iommu_dev; +} + static u32 dev_iommu_get_max_pasids(struct device *dev) { u32 max_pasids =3D 0, bits =3D 0; @@ -620,7 +629,7 @@ static void __iommu_group_remove_device(struct device *= dev) =20 list_del(&device->list); __iommu_group_free_device(group, device); - if (dev->iommu && dev->iommu->iommu_dev) + if (dev_has_iommu(dev)) iommu_deinit_device(dev); else dev->iommu_group =3D NULL; @@ -819,7 +828,7 @@ int iommu_get_group_resv_regions(struct iommu_group *gr= oup, * Non-API groups still expose reserved_regions in sysfs, * so filter out calls that get here that way. */ - if (!device->dev->iommu) + if (!dev_has_iommu(device->dev)) break; =20 INIT_LIST_HEAD(&dev_resv_regions); @@ -1224,6 +1233,12 @@ 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) +{ + lockdep_assert_held(&group->mutex); + return list_first_entry(&group->devices, struct group_device, list)->dev; +} + /** * iommu_group_for_each_dev - iterate over each device in the group * @group: the group @@ -1751,23 +1766,6 @@ __iommu_group_alloc_default_domain(struct iommu_grou= p *group, int req_type) return __iommu_group_domain_alloc(group, req_type); } =20 -/* - * Returns the iommu_ops for the devices in an iommu group. - * - * It is assumed that all devices in an iommu group are managed by a single - * IOMMU unit. Therefore, this returns the dev_iommu_ops of the first devi= ce - * in the group. - */ -static const struct iommu_ops *group_iommu_ops(struct iommu_group *group) -{ - struct group_device *device =3D - list_first_entry(&group->devices, struct group_device, list); - - lockdep_assert_held(&group->mutex); - - return dev_iommu_ops(device->dev); -} - /* * req_type of 0 means "auto" which means to select a domain based on * iommu_def_domain_type or what the driver actually supports. @@ -1775,7 +1773,7 @@ static const struct iommu_ops *group_iommu_ops(struct= iommu_group *group) static struct iommu_domain * iommu_group_alloc_default_domain(struct iommu_group *group, int req_type) { - const struct iommu_ops *ops =3D group_iommu_ops(group); + const struct iommu_ops *ops =3D dev_iommu_ops(iommu_group_first_dev(group= )); struct iommu_domain *dom; =20 lockdep_assert_held(&group->mutex); @@ -1853,7 +1851,7 @@ static int iommu_bus_notifier(struct notifier_block *= nb, static int iommu_get_def_domain_type(struct iommu_group *group, struct device *dev, int cur_type) { - const struct iommu_ops *ops =3D group_iommu_ops(group); + const struct iommu_ops *ops =3D dev_iommu_ops(dev); int type; =20 if (!ops->def_domain_type) @@ -2008,7 +2006,7 @@ bool device_iommu_capable(struct device *dev, enum io= mmu_cap cap) { const struct iommu_ops *ops; =20 - if (!dev->iommu || !dev->iommu->iommu_dev) + if (!dev_has_iommu(dev)) return false; =20 ops =3D dev_iommu_ops(dev); @@ -2105,11 +2103,9 @@ static struct iommu_domain *__iommu_domain_alloc(con= st struct iommu_ops *ops, static struct iommu_domain * __iommu_group_domain_alloc(struct iommu_group *group, unsigned int type) { - struct device *dev =3D - list_first_entry(&group->devices, struct group_device, list) - ->dev; + struct device *dev =3D iommu_group_first_dev(group); =20 - return __iommu_domain_alloc(group_iommu_ops(group), dev, type); + return __iommu_domain_alloc(dev_iommu_ops(dev), dev, type); } =20 struct iommu_domain *iommu_domain_alloc(const struct bus_type *bus) @@ -2960,8 +2956,8 @@ EXPORT_SYMBOL_GPL(iommu_fwspec_add_ids); */ int iommu_dev_enable_feature(struct device *dev, enum iommu_dev_features f= eat) { - if (dev->iommu && dev->iommu->iommu_dev) { - const struct iommu_ops *ops =3D dev->iommu->iommu_dev->ops; + if (dev_has_iommu(dev)) { + const struct iommu_ops *ops =3D dev_iommu_ops(dev); =20 if (ops->dev_enable_feat) return ops->dev_enable_feat(dev, feat); @@ -2976,8 +2972,8 @@ EXPORT_SYMBOL_GPL(iommu_dev_enable_feature); */ int iommu_dev_disable_feature(struct device *dev, enum iommu_dev_features = feat) { - if (dev->iommu && dev->iommu->iommu_dev) { - const struct iommu_ops *ops =3D dev->iommu->iommu_dev->ops; + if (dev_has_iommu(dev)) { + const struct iommu_ops *ops =3D dev_iommu_ops(dev); =20 if (ops->dev_disable_feat) return ops->dev_disable_feat(dev, feat); --=20 2.39.2.101.g768bb238c484.dirty From nobody Mon Jan 5 11:16:56 2026 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 03346E784AC for ; Mon, 2 Oct 2023 13:49:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237529AbjJBNta (ORCPT ); Mon, 2 Oct 2023 09:49:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45184 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237514AbjJBNt1 (ORCPT ); Mon, 2 Oct 2023 09:49:27 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 8896FD7 for ; Mon, 2 Oct 2023 06:49:24 -0700 (PDT) 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 BD10B143D; Mon, 2 Oct 2023 06:50:02 -0700 (PDT) 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 7384A3F762; Mon, 2 Oct 2023 06:49:23 -0700 (PDT) From: Robin Murphy To: joro@8bytes.org, will@kernel.org Cc: iommu@lists.linux.dev, jgg@nvidia.com, baolu.lu@linux.intel.com, linux-kernel@vger.kernel.org Subject: [PATCH v4 2/7] iommu: Decouple iommu_present() from bus ops Date: Mon, 2 Oct 2023 14:49:10 +0100 Message-Id: X-Mailer: git-send-email 2.39.2.101.g768bb238c484.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. Since commit 57365a04c921 ("iommu: Move bus setup to IOMMU device registration"), any registered IOMMU instance is already considered "present" for every entry in iommu_buses, so it's simply a case of validating the bus and checking we have at least once IOMMU. Signed-off-by: Robin Murphy Reviewed-by: Jason Gunthorpe --- v3: Tweak to use the ops-based check rather than group-based, to properly match the existing behaviour v4: Just look for IOMMU instances instead of managed devices --- drivers/iommu/iommu.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index f7793d1b5c3e..ef7feb0acc34 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -1988,9 +1988,28 @@ int bus_iommu_probe(const struct bus_type *bus) return 0; } =20 +/** + * 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 and aware of devices on the given= bus; + * in general it may not be the only IOMMU, and it may not have anything t= o do + * with whatever device you are ultimately interested in. + */ bool iommu_present(const struct bus_type *bus) { - return bus->iommu_ops !=3D NULL; + bool ret =3D false; + + for (int i =3D 0; i < ARRAY_SIZE(iommu_buses); i++) { + if (iommu_buses[i] =3D=3D bus) { + spin_lock(&iommu_device_lock); + ret =3D !list_empty(&iommu_device_list); + spin_unlock(&iommu_device_lock); + } + } + return ret; } EXPORT_SYMBOL_GPL(iommu_present); =20 --=20 2.39.2.101.g768bb238c484.dirty From nobody Mon Jan 5 11:16:56 2026 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 BD744E784AC for ; Mon, 2 Oct 2023 13:49:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237537AbjJBNtg (ORCPT ); Mon, 2 Oct 2023 09:49:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34408 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237527AbjJBNt3 (ORCPT ); Mon, 2 Oct 2023 09:49:29 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 94706B7 for ; Mon, 2 Oct 2023 06:49:25 -0700 (PDT) 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 CB5E01474; Mon, 2 Oct 2023 06:50:03 -0700 (PDT) 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 81A533F762; Mon, 2 Oct 2023 06:49:24 -0700 (PDT) From: Robin Murphy To: joro@8bytes.org, will@kernel.org Cc: iommu@lists.linux.dev, jgg@nvidia.com, baolu.lu@linux.intel.com, linux-kernel@vger.kernel.org Subject: [PATCH v4 3/7] iommu: Validate that devices match domains Date: Mon, 2 Oct 2023 14:49:11 +0100 Message-Id: <4dfa51b034327432793640189aa516038d3449e1.1696253096.git.robin.murphy@arm.com> X-Mailer: git-send-email 2.39.2.101.g768bb238c484.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, since they still correlate 1:1 with drivers. We can trust ourselves for internal default domain attachment, so add checks to cover all the public attach interfaces. Reviewed-by: Lu Baolu Reviewed-by: Jason Gunthorpe Signed-off-by: Robin Murphy --- v4: Cover iommu_attach_device_pasid() as well, and improve robustness against theoretical attempts to attach a noiommu group. --- drivers/iommu/iommu.c | 10 ++++++++++ include/linux/iommu.h | 1 + 2 files changed, 11 insertions(+) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index ef7feb0acc34..7c79a58ef010 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2102,6 +2102,7 @@ static struct iommu_domain *__iommu_domain_alloc(cons= t struct iommu_ops *ops, return NULL; =20 domain->type =3D type; + domain->owner =3D ops; /* * If not already set, assume all sizes by default; the driver * may override this later @@ -2267,10 +2268,16 @@ struct iommu_domain *iommu_get_dma_domain(struct de= vice *dev) static int __iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group) { + struct device *dev; + if (group->domain && group->domain !=3D group->default_domain && group->domain !=3D group->blocking_domain) return -EBUSY; =20 + dev =3D iommu_group_first_dev(group); + if (!dev_has_iommu(dev) || dev_iommu_ops(dev) !=3D domain->owner) + return -EINVAL; + return __iommu_group_set_domain(group, domain); } =20 @@ -3468,6 +3475,9 @@ int iommu_attach_device_pasid(struct iommu_domain *do= main, if (!group) return -ENODEV; =20 + if (!dev_has_iommu(dev) || dev_iommu_ops(dev) !=3D domain->owner) + return -EINVAL; + mutex_lock(&group->mutex); curr =3D xa_cmpxchg(&group->pasid_array, pasid, NULL, domain, GFP_KERNEL); if (curr) { diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 2d2802fb2c74..5c9560813d05 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -99,6 +99,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.39.2.101.g768bb238c484.dirty From nobody Mon Jan 5 11:16:56 2026 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 D8FD5E784B3 for ; Mon, 2 Oct 2023 13:49:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237572AbjJBNti (ORCPT ); Mon, 2 Oct 2023 09:49:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34452 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237515AbjJBNta (ORCPT ); Mon, 2 Oct 2023 09:49:30 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 9E0A9D9 for ; Mon, 2 Oct 2023 06:49:26 -0700 (PDT) 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 D950CC15; Mon, 2 Oct 2023 06:50:04 -0700 (PDT) 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 8FC013F762; Mon, 2 Oct 2023 06:49:25 -0700 (PDT) From: Robin Murphy To: joro@8bytes.org, will@kernel.org Cc: iommu@lists.linux.dev, jgg@nvidia.com, baolu.lu@linux.intel.com, linux-kernel@vger.kernel.org Subject: [PATCH v4 4/7] iommu: Switch __iommu_domain_alloc() to device ops Date: Mon, 2 Oct 2023 14:49:12 +0100 Message-Id: <458dd0ed839541693a49da33239b33cf4c48b8ec.1696253096.git.robin.murphy@arm.com> X-Mailer: git-send-email 2.39.2.101.g768bb238c484.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. Reviewed-by: Lu Baolu Signed-off-by: Robin Murphy --- v3: Make sure blocking domains are covered as well v4: Reinstate correct bus_for_each_dev() handling from v2 --- drivers/iommu/iommu.c | 48 ++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 7c79a58ef010..c5b5408d1dd7 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -95,8 +95,8 @@ static const char * const iommu_group_resv_type_string[] = =3D { static int iommu_bus_notifier(struct notifier_block *nb, unsigned long action, void *data); static void iommu_release_device(struct device *dev); -static struct iommu_domain * -__iommu_group_domain_alloc(struct iommu_group *group, unsigned int type); +static struct iommu_domain *__iommu_domain_alloc(struct device *dev, + unsigned type); static int __iommu_attach_device(struct iommu_domain *domain, struct device *dev); static int __iommu_attach_group(struct iommu_domain *domain, @@ -1763,7 +1763,7 @@ __iommu_group_alloc_default_domain(struct iommu_group= *group, int req_type) { if (group->default_domain && group->default_domain->type =3D=3D req_type) return group->default_domain; - return __iommu_group_domain_alloc(group, req_type); + return __iommu_domain_alloc(iommu_group_first_dev(group), req_type); } =20 /* @@ -2082,10 +2082,10 @@ 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(const struct iommu_ops *o= ps, - struct device *dev, - unsigned int type) +static struct iommu_domain *__iommu_domain_alloc(struct device *dev, + unsigned type) { + const struct iommu_ops *ops =3D dev_iommu_ops(dev); struct iommu_domain *domain; unsigned int alloc_type =3D type & IOMMU_DOMAIN_ALLOC_FLAGS; =20 @@ -2120,20 +2120,30 @@ static struct iommu_domain *__iommu_domain_alloc(co= nst struct iommu_ops *ops, return domain; } =20 -static struct iommu_domain * -__iommu_group_domain_alloc(struct iommu_group *group, unsigned int type) +static int __iommu_domain_alloc_dev(struct device *dev, void *data) { - struct device *dev =3D iommu_group_first_dev(group); + struct device **alloc_dev =3D data; =20 - return __iommu_domain_alloc(dev_iommu_ops(dev), dev, type); + if (!dev_has_iommu(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 full= y support yet. You may still need to disable one or more to get the expecte= d result here, sorry!\n"); + + *alloc_dev =3D dev; + return 0; } =20 struct iommu_domain *iommu_domain_alloc(const struct bus_type *bus) { - if (bus =3D=3D NULL || bus->iommu_ops =3D=3D NULL) + struct device *dev =3D NULL; + + /* We always check the whole bus, so the return value isn't useful */ + bus_for_each_dev(bus, NULL, &dev, __iommu_domain_alloc_dev); + if (!dev) return NULL; - return __iommu_domain_alloc(bus->iommu_ops, NULL, - IOMMU_DOMAIN_UNMANAGED); + + return __iommu_domain_alloc(dev, IOMMU_DOMAIN_UNMANAGED); } EXPORT_SYMBOL_GPL(iommu_domain_alloc); =20 @@ -3256,18 +3266,22 @@ void iommu_device_unuse_default_domain(struct devic= e *dev) =20 static int __iommu_group_alloc_blocking_domain(struct iommu_group *group) { + struct device *dev =3D iommu_group_first_dev(group); + if (group->blocking_domain) return 0; =20 - group->blocking_domain =3D - __iommu_group_domain_alloc(group, IOMMU_DOMAIN_BLOCKED); + /* noiommu groups should never be here */ + if (WARN_ON(!dev_has_iommu(dev))) + return -ENODEV; + + 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_group_domain_alloc( - group, IOMMU_DOMAIN_UNMANAGED); + group->blocking_domain =3D __iommu_domain_alloc(dev, IOMMU_DOMAIN_UNMANA= GED); if (!group->blocking_domain) return -EINVAL; } --=20 2.39.2.101.g768bb238c484.dirty From nobody Mon Jan 5 11:16:56 2026 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 1B7F6E784AC for ; Mon, 2 Oct 2023 13:49:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237577AbjJBNtk (ORCPT ); Mon, 2 Oct 2023 09:49:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34520 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237534AbjJBNte (ORCPT ); Mon, 2 Oct 2023 09:49:34 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id B9822B8 for ; Mon, 2 Oct 2023 06:49:27 -0700 (PDT) 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 F0729DA7; Mon, 2 Oct 2023 06:50:05 -0700 (PDT) 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 9DBDF3F762; Mon, 2 Oct 2023 06:49:26 -0700 (PDT) From: Robin Murphy To: joro@8bytes.org, will@kernel.org Cc: iommu@lists.linux.dev, jgg@nvidia.com, baolu.lu@linux.intel.com, linux-kernel@vger.kernel.org Subject: [PATCH v4 5/7] iommu/arm-smmu: Don't register fwnode for legacy binding Date: Mon, 2 Oct 2023 14:49:13 +0100 Message-Id: <5ae4c8ce4e83ee25a1ccfb54a1403c9371b52eca.1696253096.git.robin.murphy@arm.com> X-Mailer: git-send-email 2.39.2.101.g768bb238c484.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. Reviewed-by: Jason Gunthorpe 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 d6d1a2a55cc0..4b83a3adacd6 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -2161,7 +2161,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.39.2.101.g768bb238c484.dirty From nobody Mon Jan 5 11:16:56 2026 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 1FF70E784AD for ; Mon, 2 Oct 2023 13:49:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237589AbjJBNtn (ORCPT ); Mon, 2 Oct 2023 09:49:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34502 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237545AbjJBNtf (ORCPT ); Mon, 2 Oct 2023 09:49:35 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 305F4F2 for ; Mon, 2 Oct 2023 06:49:29 -0700 (PDT) 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 57F54143D; Mon, 2 Oct 2023 06:50:07 -0700 (PDT) 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 B5ACE3F762; Mon, 2 Oct 2023 06:49:27 -0700 (PDT) From: Robin Murphy To: joro@8bytes.org, will@kernel.org Cc: iommu@lists.linux.dev, jgg@nvidia.com, baolu.lu@linux.intel.com, linux-kernel@vger.kernel.org, "Rafael J . Wysocki" , Christoph Hellwig , Greg Kroah-Hartman Subject: [PATCH v4 6/7] iommu: Retire bus ops Date: Mon, 2 Oct 2023 14:49:14 +0100 Message-Id: X-Mailer: git-send-email 2.39.2.101.g768bb238c484.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 Acked-by: Christoph Hellwig Acked-by: Greg Kroah-Hartman Reviewed-by: Lu Baolu Reviewed-by: Jason Gunthorpe Signed-off-by: Robin Murphy --- v4: Don't forget new reference in iommu_device_register_bus() --- drivers/iommu/iommu.c | 31 ++++++++++++++++++------------- 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, 21 insertions(+), 19 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index c5b5408d1dd7..3d29434d57c6 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -148,7 +148,7 @@ struct iommu_group_attribute iommu_group_attr_##_name = =3D \ static LIST_HEAD(iommu_device_list); static DEFINE_SPINLOCK(iommu_device_lock); =20 -static struct bus_type * const iommu_buses[] =3D { +static const struct bus_type * const iommu_buses[] =3D { &platform_bus_type, #ifdef CONFIG_PCI &pci_bus_type, @@ -257,13 +257,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) @@ -273,10 +266,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; @@ -329,7 +320,6 @@ int iommu_device_register_bus(struct iommu_device *iomm= u, list_add_tail(&iommu->list, &iommu_device_list); spin_unlock(&iommu_device_lock); =20 - bus->iommu_ops =3D ops; err =3D bus_iommu_probe(bus); if (err) { iommu_device_unregister_bus(iommu, bus, nb); @@ -496,12 +486,27 @@ static void iommu_deinit_device(struct device *dev) =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_fwspec *fwspec; struct iommu_group *group; static DEFINE_MUTEX(iommu_probe_device_lock); struct group_device *gdev; 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. Otherwise, we can currently + * assume that only one of Intel, AMD, s390, PAMU or legacy SMMUv2 can + * be present, and that any of their registered instances has suitable + * ops for probing, and thus cheekily co-opt 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 254685085c82..13d959b3ba29 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -623,6 +623,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 56d93a1ffb7b..b78e66f3b34a 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -42,7 +42,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 ae10c4322754..e25aab08f873 100644 --- a/include/linux/device/bus.h +++ b/include/linux/device/bus.h @@ -62,9 +62,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 * @need_parent_lock: When probing or removing a device on this bus, the * device core should lock the device's parent. * @@ -104,8 +101,6 @@ struct bus_type { =20 const struct dev_pm_ops *pm; =20 - const struct iommu_ops *iommu_ops; - bool need_parent_lock; }; =20 diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h index f2fc203fb8a1..a52e508d1869 100644 --- a/include/linux/dma-map-ops.h +++ b/include/linux/dma-map-ops.h @@ -11,6 +11,7 @@ #include =20 struct cma; +struct iommu_ops; =20 /* * Values for struct dma_map_ops.flags: --=20 2.39.2.101.g768bb238c484.dirty From nobody Mon Jan 5 11:16:56 2026 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 1C915E784AC for ; Mon, 2 Oct 2023 13:49:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237604AbjJBNtp (ORCPT ); Mon, 2 Oct 2023 09:49:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34618 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237556AbjJBNtg (ORCPT ); Mon, 2 Oct 2023 09:49:36 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 407B4109 for ; Mon, 2 Oct 2023 06:49:30 -0700 (PDT) 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 66281C15; Mon, 2 Oct 2023 06:50:08 -0700 (PDT) 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 1C7A33F77D; Mon, 2 Oct 2023 06:49:29 -0700 (PDT) From: Robin Murphy To: joro@8bytes.org, will@kernel.org Cc: iommu@lists.linux.dev, jgg@nvidia.com, baolu.lu@linux.intel.com, linux-kernel@vger.kernel.org Subject: [PATCH v4 7/7] iommu: Clean up open-coded ownership checks Date: Mon, 2 Oct 2023 14:49:15 +0100 Message-Id: X-Mailer: git-send-email 2.39.2.101.g768bb238c484.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. Reviewed-by: Jason Gunthorpe 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 e82bf1c449a3..01ea307c7791 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -2653,9 +2653,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 4b83a3adacd6..4d09c0047892 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -1116,11 +1116,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 @@ -1357,10 +1352,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 97b2122032b2..33f3c870086c 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; @@ -372,7 +362,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 @@ -404,7 +394,7 @@ static int qcom_iommu_identity_attach(struct iommu_doma= in *identity_domain, struct iommu_domain *domain =3D iommu_get_domain_for_dev(dev); struct qcom_iommu_domain *qcom_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 int i; =20 if (domain =3D=3D identity_domain || !domain) @@ -535,7 +525,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 19ef50221c93..0a3698c33e19 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -863,16 +863,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 67e044c1a7d9..25b41222abae 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -481,9 +481,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 9c33ea6903f6..b15a8fe7ae8a 100644 --- a/drivers/iommu/sprd-iommu.c +++ b/drivers/iommu/sprd-iommu.c @@ -384,13 +384,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 17dcd826f5c2..bb2e795a80d0 100644 --- a/drivers/iommu/virtio-iommu.c +++ b/drivers/iommu/virtio-iommu.c @@ -969,9 +969,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.39.2.101.g768bb238c484.dirty