Message ID | 20190408121911.24103-6-eric.auger@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | SMMUv3 Nested Stage Setup | expand |
On 08/04/2019 13:18, Eric Auger wrote: > +int iommu_cache_invalidate(struct iommu_domain *domain, struct device *dev, > + struct iommu_cache_invalidate_info *inv_info) > +{ > + int ret = 0; > + > + if (unlikely(!domain->ops->cache_invalidate)) > + return -ENODEV; > + > + ret = domain->ops->cache_invalidate(domain, dev, inv_info); > + > + return ret; Nit: you don't really need ret The UAPI looks good to me, so Reviewed-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Hi Jean-Philippe, On 5/1/19 12:38 PM, Jean-Philippe Brucker wrote: > On 08/04/2019 13:18, Eric Auger wrote: >> +int iommu_cache_invalidate(struct iommu_domain *domain, struct device *dev, >> + struct iommu_cache_invalidate_info *inv_info) >> +{ >> + int ret = 0; >> + >> + if (unlikely(!domain->ops->cache_invalidate)) >> + return -ENODEV; >> + >> + ret = domain->ops->cache_invalidate(domain, dev, inv_info); >> + >> + return ret; > > Nit: you don't really need ret > > The UAPI looks good to me, so > > Reviewed-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com> Just to make sure, do you accept changes proposed by Jacob in https://lkml.org/lkml/2019/4/29/659 ie. - the addition of NR_IOMMU_INVAL_GRANU in enum iommu_inv_granularity and - the addition of NR_IOMMU_CACHE_TYPE Thanks Eric >
On 02/05/2019 07:58, Auger Eric wrote: > Hi Jean-Philippe, > > On 5/1/19 12:38 PM, Jean-Philippe Brucker wrote: >> On 08/04/2019 13:18, Eric Auger wrote: >>> +int iommu_cache_invalidate(struct iommu_domain *domain, struct device *dev, >>> + struct iommu_cache_invalidate_info *inv_info) >>> +{ >>> + int ret = 0; >>> + >>> + if (unlikely(!domain->ops->cache_invalidate)) >>> + return -ENODEV; >>> + >>> + ret = domain->ops->cache_invalidate(domain, dev, inv_info); >>> + >>> + return ret; >> >> Nit: you don't really need ret >> >> The UAPI looks good to me, so >> >> Reviewed-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com> > Just to make sure, do you accept changes proposed by Jacob in > https://lkml.org/lkml/2019/4/29/659 ie. > - the addition of NR_IOMMU_INVAL_GRANU in enum iommu_inv_granularity and > - the addition of NR_IOMMU_CACHE_TYPE Ah sorry, I forgot about that, I'll review the next version. Yes they can be useful (maybe call them IOMMU_INV_GRANU_NR and IOMMU_CACHE_INV_TYPE_NR?). I guess it's legal to export in UAPI values that will change over time, as VFIO also does it in its enums. Thanks, Jean
On Thu, 2 May 2019 11:53:34 +0100 Jean-Philippe Brucker <jean-philippe.brucker@arm.com> wrote: > On 02/05/2019 07:58, Auger Eric wrote: > > Hi Jean-Philippe, > > > > On 5/1/19 12:38 PM, Jean-Philippe Brucker wrote: > >> On 08/04/2019 13:18, Eric Auger wrote: > >>> +int iommu_cache_invalidate(struct iommu_domain *domain, struct > >>> device *dev, > >>> + struct iommu_cache_invalidate_info > >>> *inv_info) +{ > >>> + int ret = 0; > >>> + > >>> + if (unlikely(!domain->ops->cache_invalidate)) > >>> + return -ENODEV; > >>> + > >>> + ret = domain->ops->cache_invalidate(domain, dev, > >>> inv_info); + > >>> + return ret; > >> > >> Nit: you don't really need ret > >> > >> The UAPI looks good to me, so > >> > >> Reviewed-by: Jean-Philippe Brucker > >> <jean-philippe.brucker@arm.com> > > Just to make sure, do you accept changes proposed by Jacob in > > https://lkml.org/lkml/2019/4/29/659 ie. > > - the addition of NR_IOMMU_INVAL_GRANU in enum > > iommu_inv_granularity and > > - the addition of NR_IOMMU_CACHE_TYPE > > Ah sorry, I forgot about that, I'll review the next version. Yes they > can be useful (maybe call them IOMMU_INV_GRANU_NR and > IOMMU_CACHE_INV_TYPE_NR?). I guess it's legal to export in UAPI values > that will change over time, as VFIO also does it in its enums. > I am fine with the names. Maybe you can put this patch in your sva/api branch once you reviewed it? Having a common branch for common code makes life so much easier.
On 02/05/2019 17:46, Jacob Pan wrote: > On Thu, 2 May 2019 11:53:34 +0100 > Jean-Philippe Brucker <jean-philippe.brucker@arm.com> wrote: > >> On 02/05/2019 07:58, Auger Eric wrote: >>> Hi Jean-Philippe, >>> >>> On 5/1/19 12:38 PM, Jean-Philippe Brucker wrote: >>>> On 08/04/2019 13:18, Eric Auger wrote: >>>>> +int iommu_cache_invalidate(struct iommu_domain *domain, struct >>>>> device *dev, >>>>> + struct iommu_cache_invalidate_info >>>>> *inv_info) +{ >>>>> + int ret = 0; >>>>> + >>>>> + if (unlikely(!domain->ops->cache_invalidate)) >>>>> + return -ENODEV; >>>>> + >>>>> + ret = domain->ops->cache_invalidate(domain, dev, >>>>> inv_info); + >>>>> + return ret; >>>> >>>> Nit: you don't really need ret >>>> >>>> The UAPI looks good to me, so >>>> >>>> Reviewed-by: Jean-Philippe Brucker >>>> <jean-philippe.brucker@arm.com> >>> Just to make sure, do you accept changes proposed by Jacob in >>> https://lkml.org/lkml/2019/4/29/659 ie. >>> - the addition of NR_IOMMU_INVAL_GRANU in enum >>> iommu_inv_granularity and >>> - the addition of NR_IOMMU_CACHE_TYPE >> >> Ah sorry, I forgot about that, I'll review the next version. Yes they >> can be useful (maybe call them IOMMU_INV_GRANU_NR and >> IOMMU_CACHE_INV_TYPE_NR?). I guess it's legal to export in UAPI values >> that will change over time, as VFIO also does it in its enums. >> > I am fine with the names. Maybe you can put this patch in your sva/api > branch once you reviewed it? Having a common branch for common code > makes life so much easier. Done, with minor whitespace and name fixes Thanks, Jean
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index ede8a9bef826..6d6cb4005ca5 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -1547,6 +1547,20 @@ void iommu_detach_pasid_table(struct iommu_domain *domain) } EXPORT_SYMBOL_GPL(iommu_detach_pasid_table); +int iommu_cache_invalidate(struct iommu_domain *domain, struct device *dev, + struct iommu_cache_invalidate_info *inv_info) +{ + int ret = 0; + + if (unlikely(!domain->ops->cache_invalidate)) + return -ENODEV; + + ret = domain->ops->cache_invalidate(domain, dev, inv_info); + + return ret; +} +EXPORT_SYMBOL_GPL(iommu_cache_invalidate); + static void __iommu_detach_device(struct iommu_domain *domain, struct device *dev) { diff --git a/include/linux/iommu.h b/include/linux/iommu.h index fb9b7a8de25f..7c7c6bad1420 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -191,6 +191,7 @@ struct iommu_resv_region { * driver init to device driver init (default no) * @attach_pasid_table: attach a pasid table * @detach_pasid_table: detach the pasid table + * @cache_invalidate: invalidate translation caches * @pgsize_bitmap: bitmap of all possible supported page sizes */ struct iommu_ops { @@ -239,6 +240,9 @@ struct iommu_ops { struct iommu_pasid_table_config *cfg); void (*detach_pasid_table)(struct iommu_domain *domain); + int (*cache_invalidate)(struct iommu_domain *domain, struct device *dev, + struct iommu_cache_invalidate_info *inv_info); + unsigned long pgsize_bitmap; }; @@ -349,6 +353,9 @@ extern void iommu_detach_device(struct iommu_domain *domain, extern int iommu_attach_pasid_table(struct iommu_domain *domain, struct iommu_pasid_table_config *cfg); extern void iommu_detach_pasid_table(struct iommu_domain *domain); +extern int iommu_cache_invalidate(struct iommu_domain *domain, + struct device *dev, + struct iommu_cache_invalidate_info *inv_info); extern struct iommu_domain *iommu_get_domain_for_dev(struct device *dev); extern struct iommu_domain *iommu_get_dma_domain(struct device *dev); extern int iommu_map(struct iommu_domain *domain, unsigned long iova, @@ -797,6 +804,14 @@ int iommu_attach_pasid_table(struct iommu_domain *domain, static inline void iommu_detach_pasid_table(struct iommu_domain *domain) {} +static inline int +iommu_cache_invalidate(struct iommu_domain *domain, + struct device *dev, + struct iommu_cache_invalidate_info *inv_info) +{ + return -ENODEV; +} + #endif /* CONFIG_IOMMU_API */ #ifdef CONFIG_IOMMU_DEBUGFS diff --git a/include/uapi/linux/iommu.h b/include/uapi/linux/iommu.h index 532a64075f23..61a3fb75be3f 100644 --- a/include/uapi/linux/iommu.h +++ b/include/uapi/linux/iommu.h @@ -159,4 +159,82 @@ struct iommu_pasid_table_config { }; }; +/* defines the granularity of the invalidation */ +enum iommu_inv_granularity { + IOMMU_INV_GRANU_DOMAIN, /* domain-selective invalidation */ + IOMMU_INV_GRANU_PASID, /* pasid-selective invalidation */ + IOMMU_INV_GRANU_ADDR, /* page-selective invalidation */ +}; + +/** + * Address Selective Invalidation Structure + * + * @flags indicates the granularity of the address-selective invalidation + * - if PASID bit is set, @pasid field is populated and the invalidation + * relates to cache entries tagged with this PASID and matching the + * address range. + * - if ARCHID bit is set, @archid is populated and the invalidation relates + * to cache entries tagged with this architecture specific id and matching + * the address range. + * - Both PASID and ARCHID can be set as they may tag different caches. + * - if neither PASID or ARCHID is set, global addr invalidation applies + * - LEAF flag indicates whether only the leaf PTE caching needs to be + * invalidated and other paging structure caches can be preserved. + * @pasid: process address space id + * @archid: architecture-specific id + * @addr: first stage/level input address + * @granule_size: page/block size of the mapping in bytes + * @nb_granules: number of contiguous granules to be invalidated + */ +struct iommu_inv_addr_info { +#define IOMMU_INV_ADDR_FLAGS_PASID (1 << 0) +#define IOMMU_INV_ADDR_FLAGS_ARCHID (1 << 1) +#define IOMMU_INV_ADDR_FLAGS_LEAF (1 << 2) + __u32 flags; + __u32 archid; + __u64 pasid; + __u64 addr; + __u64 granule_size; + __u64 nb_granules; +}; + +/** + * First level/stage invalidation information + * @cache: bitfield that allows to select which caches to invalidate + * @granularity: defines the lowest granularity used for the invalidation: + * domain > pasid > addr + * + * Not all the combinations of cache/granularity make sense: + * + * type | DEV_IOTLB | IOTLB | PASID | + * granularity | | | cache | + * -------------+---------------+---------------+---------------+ + * DOMAIN | N/A | Y | Y | + * PASID | Y | Y | Y | + * ADDR | Y | Y | N/A | + * + * Invalidations by %IOMMU_INV_GRANU_ADDR use field @addr_info. + * Invalidations by %IOMMU_INV_GRANU_PASID use field @pasid. + * Invalidations by %IOMMU_INV_GRANU_DOMAIN don't take any argument. + * + * If multiple cache types are invalidated simultaneously, they all + * must support the used granularity. + */ +struct iommu_cache_invalidate_info { +#define IOMMU_CACHE_INVALIDATE_INFO_VERSION_1 1 + __u32 version; +/* IOMMU paging structure cache */ +#define IOMMU_CACHE_INV_TYPE_IOTLB (1 << 0) /* IOMMU IOTLB */ +#define IOMMU_CACHE_INV_TYPE_DEV_IOTLB (1 << 1) /* Device IOTLB */ +#define IOMMU_CACHE_INV_TYPE_PASID (1 << 2) /* PASID cache */ + __u8 cache; + __u8 granularity; + __u8 padding[2]; + union { + __u64 pasid; + struct iommu_inv_addr_info addr_info; + }; +}; + + #endif /* _UAPI_IOMMU_H */