From: Robin Murphy <robin.murphy@arm.com>
To: Jason Gunthorpe <jgg@nvidia.com>, Nicolin Chen <nicolinc@nvidia.com>
Cc: kevin.tian@intel.com, tglx@linutronix.de, maz@kernel.org,
joro@8bytes.org, will@kernel.org, shuah@kernel.org,
iommu@lists.linux.dev, linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-kselftest@vger.kernel.org, eric.auger@redhat.com,
baolu.lu@linux.intel.com, yi.l.liu@intel.com,
yury.norov@gmail.com, jacob.pan@linux.microsoft.com,
patches@lists.linux.dev
Subject: Re: [PATCH v2 7/7] iommu: Turn iova_cookie to dma-iommu private pointer
Date: Fri, 21 Feb 2025 15:23:22 +0000 [thread overview]
Message-ID: <b9b4bfe3-9d2d-4009-b3d4-e179e8bccd9a@arm.com> (raw)
In-Reply-To: <20250221143959.GA272220@nvidia.com>
On 2025-02-21 2:39 pm, Jason Gunthorpe wrote:
> On Wed, Feb 19, 2025 at 05:31:42PM -0800, Nicolin Chen wrote:
>> Now that iommufd does not rely on dma-iommu.c for any purpose. We can
>> combine the dma-iommu.c iova_cookie and the iommufd_hwpt under the same
>> union. This union is effectively 'owner data' and can be used by the
>> entity that allocated the domain. Note that legacy vfio type1 flows
>> continue to use dma-iommu.c for sw_msi and still need iova_cookie.
>>
>> Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
>> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
>> ---
>> include/linux/iommu.h | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
>> index e93d2e918599..99dd72998cb7 100644
>> --- a/include/linux/iommu.h
>> +++ b/include/linux/iommu.h
>> @@ -216,7 +216,6 @@ struct iommu_domain {
>> 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;
>> int (*iopf_handler)(struct iopf_group *group);
>>
>> #if IS_ENABLED(CONFIG_IRQ_MSI_IOMMU)
>> @@ -225,6 +224,7 @@ struct iommu_domain {
>> #endif
>>
>> union { /* Pointer usable by owner of the domain */
>> + struct iommu_dma_cookie *iova_cookie; /* dma-iommu */
>> struct iommufd_hw_pagetable *iommufd_hwpt; /* iommufd */
>> };
>
> Ugh, there is a problem here:
>
> void iommu_domain_free(struct iommu_domain *domain)
> {
> if (domain->type == IOMMU_DOMAIN_SVA)
> mmdrop(domain->mm);
> iommu_put_dma_cookie(domain);
>
> It calls into dma-iommu for all domain types
>
> And if !CONFIG_IRQ_MSI_IOMMU then this isn't possible to protect it
> against iommufd owning the cookie union:
>
> #if IS_ENABLED(CONFIG_IRQ_MSI_IOMMU)
> if (domain->sw_msi != iommu_dma_sw_msi)
> return;
> #endif
>
> I came up with the below, but I will drop this patch for now you can
> repost it as a cleanup series..
Eww... What's the issue with just checking the domain type in
iommu_put_dma_cookie()? Is is that IOMMUFD and VFIO type 1 are both
doing their own different thing with IOMMU_DOMAIN_UNMANAGED?
In general it seems like a bad smell to have a union in a structure with
not enough information within that structire itself to know which union
member is valid... :/
Thanks,
Robin.
>
> Jason
>
> diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
> index 3b58244e6344a5..31d53552dc4790 100644
> --- a/drivers/iommu/dma-iommu.c
> +++ b/drivers/iommu/dma-iommu.c
> @@ -418,6 +418,7 @@ int iommu_get_dma_cookie(struct iommu_domain *domain)
> * number of PAGE_SIZE mappings necessary to cover every MSI doorbell address
> * used by the devices attached to @domain.
> */
> +#if IS_ENABLED(CONFIG_IRQ_MSI_IOMMU)
> int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base)
> {
> struct iommu_dma_cookie *cookie;
> @@ -439,6 +440,13 @@ int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base)
> }
> EXPORT_SYMBOL(iommu_get_msi_cookie);
>
> +void iommu_put_msi_cookie(struct iommu_domain *domain)
> +{
> + iommu_put_dma_cookie(domain);
> +}
> +EXPORT_SYMBOL_GPL(iommu_put_msi_cookie);
> +#endif
> +
> /**
> * iommu_put_dma_cookie - Release a domain's DMA mapping resources
> * @domain: IOMMU domain previously prepared by iommu_get_dma_cookie() or
> @@ -449,8 +457,10 @@ void iommu_put_dma_cookie(struct iommu_domain *domain)
> struct iommu_dma_cookie *cookie = domain->iova_cookie;
> struct iommu_dma_msi_page *msi, *tmp;
>
> +#if IS_ENABLED(CONFIG_IRQ_MSI_IOMMU)
> if (domain->sw_msi != iommu_dma_sw_msi)
> return;
> +#endif
>
> if (!cookie)
> return;
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 022bf96a18c5e4..f07544b290e5b1 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -456,6 +456,12 @@ static int iommu_init_device(struct device *dev, const struct iommu_ops *ops)
> return ret;
> }
>
> +static void iommu_default_domain_free(struct iommu_domain *domain)
> +{
> + iommu_put_dma_cookie(domain);
> + iommu_domain_free(domain);
> +}
> +
> static void iommu_deinit_device(struct device *dev)
> {
> struct iommu_group *group = dev->iommu_group;
> @@ -494,7 +500,7 @@ static void iommu_deinit_device(struct device *dev)
> */
> if (list_empty(&group->devices)) {
> if (group->default_domain) {
> - iommu_domain_free(group->default_domain);
> + iommu_default_domain_free(group->default_domain);
> group->default_domain = NULL;
> }
> if (group->blocking_domain) {
> @@ -2023,7 +2029,6 @@ void iommu_domain_free(struct iommu_domain *domain)
> {
> if (domain->type == IOMMU_DOMAIN_SVA)
> mmdrop(domain->mm);
> - iommu_put_dma_cookie(domain);
> if (domain->ops->free)
> domain->ops->free(domain);
> }
> @@ -3000,7 +3005,7 @@ static int iommu_setup_default_domain(struct iommu_group *group,
>
> out_free_old:
> if (old_dom)
> - iommu_domain_free(old_dom);
> + iommu_default_domain_free(old_dom);
> return ret;
>
> err_restore_domain:
> @@ -3009,7 +3014,7 @@ static int iommu_setup_default_domain(struct iommu_group *group,
> group, old_dom, IOMMU_SET_DOMAIN_MUST_SUCCEED);
> err_restore_def_domain:
> if (old_dom) {
> - iommu_domain_free(dom);
> + iommu_default_domain_free(dom);
> group->default_domain = old_dom;
> }
> return ret;
> diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
> index 50ebc9593c9d70..b5bb946c9c1b19 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -2271,6 +2271,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
> if (!iommu_attach_group(d->domain,
> group->iommu_group)) {
> list_add(&group->next, &d->group_list);
> + iommu_put_msi_cookie(domain->domain);
> iommu_domain_free(domain->domain);
> kfree(domain);
> goto done;
> @@ -2316,6 +2317,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
> out_detach:
> iommu_detach_group(domain->domain, group->iommu_group);
> out_domain:
> + iommu_put_msi_cookie(domain->domain);
> iommu_domain_free(domain->domain);
> vfio_iommu_iova_free(&iova_copy);
> vfio_iommu_resv_free(&group_resv_regions);
> @@ -2496,6 +2498,7 @@ static void vfio_iommu_type1_detach_group(void *iommu_data,
> vfio_iommu_unmap_unpin_reaccount(iommu);
> }
> }
> + iommu_put_msi_cookie(domain->domain);
> iommu_domain_free(domain->domain);
> list_del(&domain->next);
> kfree(domain);
> @@ -2567,6 +2570,7 @@ static void vfio_release_domain(struct vfio_domain *domain)
> kfree(group);
> }
>
> + iommu_put_msi_cookie(domain->domain);
> iommu_domain_free(domain->domain);
> }
>
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index 99dd72998cb7f7..082274e8ba6a3d 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -1534,12 +1534,16 @@ void iommu_debugfs_setup(void);
> static inline void iommu_debugfs_setup(void) {}
> #endif
>
> -#ifdef CONFIG_IOMMU_DMA
> +#if defined(CONFIG_IOMMU_DMA) && IS_ENABLED(CONFIG_IRQ_MSI_IOMMU)
> int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base);
> +void iommu_put_msi_cookie(struct iommu_domain *domain);
> #else /* CONFIG_IOMMU_DMA */
> static inline int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base)
> {
> - return -ENODEV;
> + return 0;
> +}
> +static inline void iommu_put_msi_cookie(struct iommu_domain *domain)
> +{
> }
> #endif /* CONFIG_IOMMU_DMA */
>
next prev parent reply other threads:[~2025-02-21 15:23 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-20 1:31 [PATCH v2 0/7] iommu: Add MSI mapping support with nested SMMU (Part-1 core) Nicolin Chen
2025-02-20 1:31 ` [PATCH v2 1/7] genirq/msi: Store the IOMMU IOVA directly in msi_desc instead of iommu_cookie Nicolin Chen
2025-02-21 9:28 ` Thomas Gleixner
2025-02-21 11:10 ` Joerg Roedel
2025-02-21 13:41 ` Jason Gunthorpe
2025-02-21 14:00 ` Joerg Roedel
2025-02-21 14:05 ` Jason Gunthorpe
2025-02-20 1:31 ` [PATCH v2 2/7] genirq/msi: Refactor iommu_dma_compose_msi_msg() Nicolin Chen
2025-02-21 9:28 ` Thomas Gleixner
2025-02-20 1:31 ` [PATCH v2 3/7] iommu: Make iommu_dma_prepare_msi() into a generic operation Nicolin Chen
2025-02-21 15:39 ` Robin Murphy
2025-02-21 16:44 ` Jason Gunthorpe
2025-02-27 11:21 ` Robin Murphy
2025-02-27 15:32 ` Jason Gunthorpe
2025-02-27 17:46 ` Nicolin Chen
2025-02-27 19:47 ` Jason Gunthorpe
2025-02-20 1:31 ` [PATCH v2 4/7] irqchip: Have CONFIG_IRQ_MSI_IOMMU be selected by irqchips that need it Nicolin Chen
2025-02-21 9:30 ` Thomas Gleixner
2025-02-21 14:48 ` Jason Gunthorpe
2025-02-20 1:31 ` [PATCH v2 5/7] iommu: Turn fault_data to iommufd private pointer Nicolin Chen
2025-02-20 17:50 ` Jason Gunthorpe
2025-02-20 1:31 ` [PATCH v2 6/7] iommufd: Implement sw_msi support natively Nicolin Chen
2025-02-21 14:51 ` Jason Gunthorpe
2025-02-27 19:33 ` Jason Gunthorpe
2025-02-20 1:31 ` [PATCH v2 7/7] iommu: Turn iova_cookie to dma-iommu private pointer Nicolin Chen
2025-02-20 17:50 ` Jason Gunthorpe
2025-02-21 14:39 ` Jason Gunthorpe
2025-02-21 15:23 ` Robin Murphy [this message]
2025-02-21 16:48 ` Jason Gunthorpe
2025-02-26 2:25 ` Nicolin Chen
2025-02-26 17:36 ` Jason Gunthorpe
2025-02-26 18:57 ` Nicolin Chen
2025-02-26 19:18 ` Jason Gunthorpe
2025-02-21 14:59 ` [PATCH v2 0/7] iommu: Add MSI mapping support with nested SMMU (Part-1 core) Jason Gunthorpe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=b9b4bfe3-9d2d-4009-b3d4-e179e8bccd9a@arm.com \
--to=robin.murphy@arm.com \
--cc=baolu.lu@linux.intel.com \
--cc=eric.auger@redhat.com \
--cc=iommu@lists.linux.dev \
--cc=jacob.pan@linux.microsoft.com \
--cc=jgg@nvidia.com \
--cc=joro@8bytes.org \
--cc=kevin.tian@intel.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=maz@kernel.org \
--cc=nicolinc@nvidia.com \
--cc=patches@lists.linux.dev \
--cc=shuah@kernel.org \
--cc=tglx@linutronix.de \
--cc=will@kernel.org \
--cc=yi.l.liu@intel.com \
--cc=yury.norov@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox