Messages in this thread | | | Date | Sun, 31 Jul 2022 20:19:04 +0800 | Subject | Re: [PATCH v10 05/12] iommu: Add IOMMU SVA domain support | From | Yi Liu <> |
| |
On 2022/7/5 13:07, Lu Baolu wrote: > The sva iommu_domain represents a hardware pagetable that the IOMMU > hardware could use for SVA translation. This adds some infrastructure > to support SVA domain in the iommu common layer. It includes: > > - Extend the iommu_domain to support a new IOMMU_DOMAIN_SVA domain > type. The IOMMU drivers that support allocation of the SVA domain > should provide its own sva domain specific iommu_domain_ops. > - Add a helper to allocate an SVA domain. The iommu_domain_free() > is still used to free an SVA domain. > > The report_iommu_fault() should be replaced by the new > iommu_report_device_fault(). Leave the existing fault handler with the > existing users and the newly added SVA members excludes it. > > Suggested-by: Jean-Philippe Brucker <jean-philippe@linaro.org> > Suggested-by: Jason Gunthorpe <jgg@nvidia.com> > Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> > Reviewed-by: Jean-Philippe Brucker <jean-philippe@linaro.org> > Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org> > Tested-by: Tony Zhu <tony.zhu@intel.com> > --- > include/linux/iommu.h | 24 ++++++++++++++++++++++-- > drivers/iommu/iommu.c | 20 ++++++++++++++++++++ > 2 files changed, 42 insertions(+), 2 deletions(-)
Reviewed-by: Yi Liu <yi.l.liu@intel.com>
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h > index f2b5aa7efe43..42f0418dc22c 100644 > --- a/include/linux/iommu.h > +++ b/include/linux/iommu.h > @@ -64,6 +64,8 @@ struct iommu_domain_geometry { > #define __IOMMU_DOMAIN_PT (1U << 2) /* Domain is identity mapped */ > #define __IOMMU_DOMAIN_DMA_FQ (1U << 3) /* DMA-API uses flush queue */ > > +#define __IOMMU_DOMAIN_SVA (1U << 4) /* Shared process address space */ > + > /* > * This are the possible domain-types > * > @@ -77,6 +79,8 @@ struct iommu_domain_geometry { > * certain optimizations for these domains > * IOMMU_DOMAIN_DMA_FQ - As above, but definitely using batched TLB > * invalidation. > + * IOMMU_DOMAIN_SVA - DMA addresses are shared process address > + * spaces represented by mm_struct's. > */ > #define IOMMU_DOMAIN_BLOCKED (0U) > #define IOMMU_DOMAIN_IDENTITY (__IOMMU_DOMAIN_PT) > @@ -86,15 +90,23 @@ struct iommu_domain_geometry { > #define IOMMU_DOMAIN_DMA_FQ (__IOMMU_DOMAIN_PAGING | \ > __IOMMU_DOMAIN_DMA_API | \ > __IOMMU_DOMAIN_DMA_FQ) > +#define IOMMU_DOMAIN_SVA (__IOMMU_DOMAIN_SVA) > > struct iommu_domain { > unsigned type; > const struct iommu_domain_ops *ops; > unsigned long pgsize_bitmap; /* Bitmap of page sizes in use */ > - iommu_fault_handler_t handler; > - void *handler_token; > struct iommu_domain_geometry geometry; > struct iommu_dma_cookie *iova_cookie; > + union { > + struct { > + iommu_fault_handler_t handler; > + void *handler_token; > + }; > + struct { /* IOMMU_DOMAIN_SVA */ > + struct mm_struct *mm; > + }; > + }; > }; > > static inline bool iommu_is_dma_domain(struct iommu_domain *domain) > @@ -685,6 +697,8 @@ int iommu_group_claim_dma_owner(struct iommu_group *group, void *owner); > void iommu_group_release_dma_owner(struct iommu_group *group); > bool iommu_group_dma_owner_claimed(struct iommu_group *group); > > +struct iommu_domain *iommu_sva_domain_alloc(struct device *dev, > + struct mm_struct *mm); > int iommu_attach_device_pasid(struct iommu_domain *domain, struct device *dev, > ioasid_t pasid); > void iommu_detach_device_pasid(struct iommu_domain *domain, struct device *dev, > @@ -1063,6 +1077,12 @@ static inline bool iommu_group_dma_owner_claimed(struct iommu_group *group) > return false; > } > > +static inline struct iommu_domain * > +iommu_sva_domain_alloc(struct device *dev, struct mm_struct *mm) > +{ > + return NULL; > +} > + > static inline int iommu_attach_device_pasid(struct iommu_domain *domain, > struct device *dev, ioasid_t pasid) > { > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c > index be48b09371f4..10479c5e4d23 100644 > --- a/drivers/iommu/iommu.c > +++ b/drivers/iommu/iommu.c > @@ -27,6 +27,7 @@ > #include <linux/module.h> > #include <linux/cc_platform.h> > #include <trace/events/iommu.h> > +#include <linux/sched/mm.h> > > static struct kset *iommu_group_kset; > static DEFINE_IDA(iommu_group_ida); > @@ -1957,6 +1958,8 @@ EXPORT_SYMBOL_GPL(iommu_domain_alloc); > > void iommu_domain_free(struct iommu_domain *domain) > { > + if (domain->type == IOMMU_DOMAIN_SVA) > + mmdrop(domain->mm); > iommu_put_dma_cookie(domain); > domain->ops->free(domain); > } > @@ -3274,6 +3277,23 @@ bool iommu_group_dma_owner_claimed(struct iommu_group *group) > } > EXPORT_SYMBOL_GPL(iommu_group_dma_owner_claimed); > > +struct iommu_domain *iommu_sva_domain_alloc(struct device *dev, > + struct mm_struct *mm) > +{ > + const struct iommu_ops *ops = dev_iommu_ops(dev); > + struct iommu_domain *domain; > + > + domain = ops->domain_alloc(IOMMU_DOMAIN_SVA); > + if (!domain) > + return NULL; > + > + domain->type = IOMMU_DOMAIN_SVA; > + mmgrab(mm); > + domain->mm = mm; > + > + return domain; > +} > + > static bool iommu_group_immutable_singleton(struct iommu_group *group, > struct device *dev) > {
-- Regards, Yi Liu
| |