On Mon, Aug 07, 2017 at 05:25:44PM +1000, Alexey Kardashevskiy wrote: > This introduces capabilities to IOMMU groups. The first defined > capability is IOMMU_GROUP_CAP_ISOLATE_MSIX which tells the IOMMU > group users that a particular IOMMU group is capable of MSIX message > filtering; this is useful when deciding whether or not to allow mapping > of MSIX table to the userspace. Various architectures will enable it > when they decide that it is safe to do so. > > Signed-off-by: Alexey Kardashevskiy Reviewed-by: David Gibson This seems like a reasonable concept that's probably useful for something, whether or not it's the best approach for the problem at hand. > --- > include/linux/iommu.h | 20 ++++++++++++++++++++ > drivers/iommu/iommu.c | 28 ++++++++++++++++++++++++++++ > 2 files changed, 48 insertions(+) > > diff --git a/include/linux/iommu.h b/include/linux/iommu.h > index 2cb54adc4a33..6b6f3c2f4904 100644 > --- a/include/linux/iommu.h > +++ b/include/linux/iommu.h > @@ -155,6 +155,9 @@ struct iommu_resv_region { > enum iommu_resv_type type; > }; > > +/* IOMMU group capabilities */ > +#define IOMMU_GROUP_CAP_ISOLATE_MSIX (1U) > + > #ifdef CONFIG_IOMMU_API > > /** > @@ -312,6 +315,11 @@ extern void *iommu_group_get_iommudata(struct iommu_group *group); > extern void iommu_group_set_iommudata(struct iommu_group *group, > void *iommu_data, > void (*release)(void *iommu_data)); > +extern void iommu_group_set_caps(struct iommu_group *group, > + unsigned long clearcaps, > + unsigned long setcaps); > +extern bool iommu_group_is_capable(struct iommu_group *group, > + unsigned long cap); > extern int iommu_group_set_name(struct iommu_group *group, const char *name); > extern int iommu_group_add_device(struct iommu_group *group, > struct device *dev); > @@ -513,6 +521,18 @@ static inline void iommu_group_set_iommudata(struct iommu_group *group, > { > } > > +static inline void iommu_group_set_caps(struct iommu_group *group, > + unsigned long clearcaps, > + unsigned long setcaps) > +{ > +} > + > +static inline bool iommu_group_is_capable(struct iommu_group *group, > + unsigned long cap) > +{ > + return false; > +} > + > static inline int iommu_group_set_name(struct iommu_group *group, > const char *name) > { > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c > index 3f6ea160afed..6b2c34fe2c3d 100644 > --- a/drivers/iommu/iommu.c > +++ b/drivers/iommu/iommu.c > @@ -52,6 +52,7 @@ struct iommu_group { > void (*iommu_data_release)(void *iommu_data); > char *name; > int id; > + unsigned long caps; > struct iommu_domain *default_domain; > struct iommu_domain *domain; > }; > @@ -447,6 +448,33 @@ void iommu_group_set_iommudata(struct iommu_group *group, void *iommu_data, > EXPORT_SYMBOL_GPL(iommu_group_set_iommudata); > > /** > + * iommu_group_set_caps - Change the group capabilities > + * @group: the group > + * @clearcaps: capabilities mask to remove > + * @setcaps: capabilities mask to add > + * > + * IOMMU groups can be capable of various features which device drivers > + * may read and adjust the behavior. > + */ > +void iommu_group_set_caps(struct iommu_group *group, > + unsigned long clearcaps, unsigned long setcaps) > +{ > + group->caps &= ~clearcaps; > + group->caps |= setcaps; > +} > +EXPORT_SYMBOL_GPL(iommu_group_set_caps); > + > +/** > + * iommu_group_is_capable - Returns if a group capability is present > + * @group: the group > + */ > +bool iommu_group_is_capable(struct iommu_group *group, unsigned long cap) > +{ > + return !!(group->caps & cap); > +} > +EXPORT_SYMBOL_GPL(iommu_group_is_capable); > + > +/** > * iommu_group_set_name - set name for a group > * @group: the group > * @name: name -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson