Re: [PATCH v3 02/14] iommu: Report domain nesting info
On Tue, Jun 30, 2020 at 02:00:49AM +, Tian, Kevin wrote: > > From: Liu, Yi L > > Sent: Monday, June 29, 2020 8:23 PM > > > > Hi Stefan, > > > > > From: Stefan Hajnoczi > > > Sent: Monday, June 29, 2020 5:25 PM > > > > > > On Wed, Jun 24, 2020 at 01:55:15AM -0700, Liu Yi L wrote: > > > > +/* > > > > + * struct iommu_nesting_info - Information for nesting-capable IOMMU. > > > > + * user space should check it before using > > > > + * nesting capability. > > > > + * > > > > + * @size: size of the whole structure > > > > + * @format:PASID table entry format, the same definition with > > > > + * @format of struct iommu_gpasid_bind_data. > > > > + * @features: supported nesting features. > > > > + * @flags: currently reserved for future extension. > > > > + * @data: vendor specific cap info. > > > > + * > > > > + * > > > > +---++ > > > > + * | feature | Notes > > > > | > > > > + * > > > > > +===+=== > > > > > =+ > > > > + * | SYSWIDE_PASID | Kernel manages PASID in system wide, PASIDs > > used | > > > > + * | | in the system should be allocated by host kernel > > > > | > > > > + * > > > > +---++ > > > > + * | BIND_PGTBL| bind page tables to host PASID, the PASID could > > > > | > > > > + * | | either be a host PASID passed in bind request or > > > > | > > > > + * | | default PASIDs (e.g. default PASID of > > > > aux-domain) | > > > > + * > > > > +---++ > > > > + * | CACHE_INVLD | mandatory feature for nesting capable IOMMU > > | > > > > + * > > > > +---++ > > > > > > This feature description is vague about what CACHE_INVLD does and how > > to > > > use it. If I understand correctly, the presence of this feature means > > > that VFIO_IOMMU_NESTING_OP_CACHE_INVLD must be used? > > > > > > The same kind of clarification could be done for SYSWIDE_PASID and > > > BIND_PGTBL too. > > > > For SYSWIDE_PASID and BIND_PGTBL, yes, presence of the feature bit > > means must use. So the two are requirements to user space if it wants > > to setup nesting. While for CACHE_INVLD, it's kind of availability > > here. How about removing CACHE_INVLD as presence of BIND_PGTBL should > > indicates support of CACHE_INVLD? > > > > So far this assumption is correct but it may not be true when thinking > forward. > For example, a vendor might find a way to allow the owner of 1st-level page > table to directly invalidate cache w/o going through host IOMMU driver. From > this angle I feel explicitly reporting this capability is more robust. > > Regarding to the description, what about below? > > -- > SYSWIDE_PASID: PASIDs are managed in system-wide, instead of per device. > When a device is assigned to userspace or VM, proper uAPI (provided by > userspace driver framework, e.g. VFIO) must be used to allocate/free PASIDs > for the assigned device. > > BIND_PGTBL: The owner of the first-level/stage-1 page table must explicitly > bind the page table to associated PASID (either the one specified in bind > request or the default PASID of the iommu domain), through VFIO_IOMMU > _NESTING_OP > > CACHE_INVLD: The owner of the first-level/stage-1 page table must > explicitly invalidate the IOMMU cache through VFIO_IOMMU_NESTING_OP, > according to vendor-specific requirement when changing the page table. > -- Mentioning the API to allocate/free PASIDs and VFIO_IOMMU_NESTING_OP has made this clearer. This lets someone reading the documentation know where to look for further information on using these features. Thank you! Stefan signature.asc Description: PGP signature
RE: [PATCH v3 02/14] iommu: Report domain nesting info
> From: Alex Williamson > Sent: Friday, July 3, 2020 1:55 AM > > On Wed, 24 Jun 2020 01:55:15 -0700 > Liu Yi L wrote: > > > IOMMUs that support nesting translation needs report the capability > > info to userspace, e.g. the format of first level/stage paging structures. > > > > This patch reports nesting info by DOMAIN_ATTR_NESTING. Caller can get > > nesting info after setting DOMAIN_ATTR_NESTING. > > > > v2 -> v3: > > *) remvoe cap/ecap_mask in iommu_nesting_info. > > *) reuse DOMAIN_ATTR_NESTING to get nesting info. > > *) return an empty iommu_nesting_info for SMMU drivers per Jean' > >suggestion. > > > > Cc: Kevin Tian > > CC: Jacob Pan > > Cc: Alex Williamson > > Cc: Eric Auger > > Cc: Jean-Philippe Brucker > > Cc: Joerg Roedel > > Cc: Lu Baolu > > Signed-off-by: Liu Yi L > > Signed-off-by: Jacob Pan > > --- > > drivers/iommu/arm-smmu-v3.c | 29 -- > > drivers/iommu/arm-smmu.c| 29 -- > > include/uapi/linux/iommu.h | 59 > > + > > 3 files changed, 113 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c > > index f578677..0c45d4d 100644 > > --- a/drivers/iommu/arm-smmu-v3.c > > +++ b/drivers/iommu/arm-smmu-v3.c > > @@ -3019,6 +3019,32 @@ static struct iommu_group > *arm_smmu_device_group(struct device *dev) > > return group; > > } > > > > +static int arm_smmu_domain_nesting_info(struct arm_smmu_domain > *smmu_domain, > > + void *data) > > +{ > > + struct iommu_nesting_info *info = (struct iommu_nesting_info *) data; > > + u32 size; > > + > > + if (!info || smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED) > > + return -ENODEV; > > + > > + size = sizeof(struct iommu_nesting_info); > > + > > + /* > > +* if provided buffer size is not equal to the size, should > > +* return 0 and also the expected buffer size to caller. > > +*/ > > + if (info->size != size) { > > + info->size = size; > > + return 0; > > + } > > + > > + /* report an empty iommu_nesting_info for now */ > > + memset(info, 0x0, size); > > + info->size = size; > > + return 0; > > +} > > + > > static int arm_smmu_domain_get_attr(struct iommu_domain *domain, > > enum iommu_attr attr, void *data) { @@ - > 3028,8 +3054,7 @@ > > static int arm_smmu_domain_get_attr(struct iommu_domain *domain, > > case IOMMU_DOMAIN_UNMANAGED: > > switch (attr) { > > case DOMAIN_ATTR_NESTING: > > - *(int *)data = (smmu_domain->stage == > ARM_SMMU_DOMAIN_NESTED); > > - return 0; > > + return arm_smmu_domain_nesting_info(smmu_domain, > data); > > default: > > return -ENODEV; > > } > > diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index > > 243bc4c..908607d 100644 > > --- a/drivers/iommu/arm-smmu.c > > +++ b/drivers/iommu/arm-smmu.c > > @@ -1506,6 +1506,32 @@ static struct iommu_group > *arm_smmu_device_group(struct device *dev) > > return group; > > } > > > > +static int arm_smmu_domain_nesting_info(struct arm_smmu_domain > *smmu_domain, > > + void *data) > > +{ > > + struct iommu_nesting_info *info = (struct iommu_nesting_info *) data; > > + u32 size; > > + > > + if (!info || smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED) > > + return -ENODEV; > > + > > + size = sizeof(struct iommu_nesting_info); > > + > > + /* > > +* if provided buffer size is not equal to the size, should > > +* return 0 and also the expected buffer size to caller. > > +*/ > > + if (info->size != size) { > > + info->size = size; > > + return 0; > > + } > > + > > + /* report an empty iommu_nesting_info for now */ > > + memset(info, 0x0, size); > > + info->size = size; > > + return 0; > > +} > > + > > static int arm_smmu_domain_get_attr(struct iommu_domain *domain, > > enum iommu_attr attr, void *data) { @@ - > 1515,8 +1541,7 @@ > > static int arm_smmu_domain_get_attr(struct iommu_domain *domain, > > case IOMMU_DOMAIN_UNMANAGED: > > switch (attr) { > > case DOMAIN_ATTR_NESTING: > > - *(int *)data = (smmu_domain->stage == > ARM_SMMU_DOMAIN_NESTED); > > - return 0; > > + return arm_smmu_domain_nesting_info(smmu_domain, > data); > > default: > > return -ENODEV; > > } > > diff --git a/include/uapi/linux/iommu.h b/include/uapi/linux/iommu.h > > index 1afc661..898c99a 100644 > > --- a/include/uapi/linux/iommu.h > > +++ b/include/uapi/linux/iommu.h > > @@ -332,4 +332,63 @@ struct iommu_gpasid_bind_data { > > } vendor; > > }; > > > > +/* > > + * struct iommu_nesting_info - Information for nesting-capable IOMMU.
Re: [PATCH v3 02/14] iommu: Report domain nesting info
On Wed, 24 Jun 2020 01:55:15 -0700 Liu Yi L wrote: > IOMMUs that support nesting translation needs report the capability info > to userspace, e.g. the format of first level/stage paging structures. > > This patch reports nesting info by DOMAIN_ATTR_NESTING. Caller can get > nesting info after setting DOMAIN_ATTR_NESTING. > > v2 -> v3: > *) remvoe cap/ecap_mask in iommu_nesting_info. > *) reuse DOMAIN_ATTR_NESTING to get nesting info. > *) return an empty iommu_nesting_info for SMMU drivers per Jean' >suggestion. > > Cc: Kevin Tian > CC: Jacob Pan > Cc: Alex Williamson > Cc: Eric Auger > Cc: Jean-Philippe Brucker > Cc: Joerg Roedel > Cc: Lu Baolu > Signed-off-by: Liu Yi L > Signed-off-by: Jacob Pan > --- > drivers/iommu/arm-smmu-v3.c | 29 -- > drivers/iommu/arm-smmu.c| 29 -- > include/uapi/linux/iommu.h | 59 > + > 3 files changed, 113 insertions(+), 4 deletions(-) > > diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c > index f578677..0c45d4d 100644 > --- a/drivers/iommu/arm-smmu-v3.c > +++ b/drivers/iommu/arm-smmu-v3.c > @@ -3019,6 +3019,32 @@ static struct iommu_group > *arm_smmu_device_group(struct device *dev) > return group; > } > > +static int arm_smmu_domain_nesting_info(struct arm_smmu_domain *smmu_domain, > + void *data) > +{ > + struct iommu_nesting_info *info = (struct iommu_nesting_info *) data; > + u32 size; > + > + if (!info || smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED) > + return -ENODEV; > + > + size = sizeof(struct iommu_nesting_info); > + > + /* > + * if provided buffer size is not equal to the size, should > + * return 0 and also the expected buffer size to caller. > + */ > + if (info->size != size) { > + info->size = size; > + return 0; > + } > + > + /* report an empty iommu_nesting_info for now */ > + memset(info, 0x0, size); > + info->size = size; > + return 0; > +} > + > static int arm_smmu_domain_get_attr(struct iommu_domain *domain, > enum iommu_attr attr, void *data) > { > @@ -3028,8 +3054,7 @@ static int arm_smmu_domain_get_attr(struct iommu_domain > *domain, > case IOMMU_DOMAIN_UNMANAGED: > switch (attr) { > case DOMAIN_ATTR_NESTING: > - *(int *)data = (smmu_domain->stage == > ARM_SMMU_DOMAIN_NESTED); > - return 0; > + return arm_smmu_domain_nesting_info(smmu_domain, data); > default: > return -ENODEV; > } > diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c > index 243bc4c..908607d 100644 > --- a/drivers/iommu/arm-smmu.c > +++ b/drivers/iommu/arm-smmu.c > @@ -1506,6 +1506,32 @@ static struct iommu_group > *arm_smmu_device_group(struct device *dev) > return group; > } > > +static int arm_smmu_domain_nesting_info(struct arm_smmu_domain *smmu_domain, > + void *data) > +{ > + struct iommu_nesting_info *info = (struct iommu_nesting_info *) data; > + u32 size; > + > + if (!info || smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED) > + return -ENODEV; > + > + size = sizeof(struct iommu_nesting_info); > + > + /* > + * if provided buffer size is not equal to the size, should > + * return 0 and also the expected buffer size to caller. > + */ > + if (info->size != size) { > + info->size = size; > + return 0; > + } > + > + /* report an empty iommu_nesting_info for now */ > + memset(info, 0x0, size); > + info->size = size; > + return 0; > +} > + > static int arm_smmu_domain_get_attr(struct iommu_domain *domain, > enum iommu_attr attr, void *data) > { > @@ -1515,8 +1541,7 @@ static int arm_smmu_domain_get_attr(struct iommu_domain > *domain, > case IOMMU_DOMAIN_UNMANAGED: > switch (attr) { > case DOMAIN_ATTR_NESTING: > - *(int *)data = (smmu_domain->stage == > ARM_SMMU_DOMAIN_NESTED); > - return 0; > + return arm_smmu_domain_nesting_info(smmu_domain, data); > default: > return -ENODEV; > } > diff --git a/include/uapi/linux/iommu.h b/include/uapi/linux/iommu.h > index 1afc661..898c99a 100644 > --- a/include/uapi/linux/iommu.h > +++ b/include/uapi/linux/iommu.h > @@ -332,4 +332,63 @@ struct iommu_gpasid_bind_data { > } vendor; > }; > > +/* > + * struct iommu_nesting_info - Information for nesting-capable IOMMU. > + * user space should check it before using > + * nesting capability. > + * > + * @size:size of the whole structure > + * @format: PASID table
RE: [PATCH v3 02/14] iommu: Report domain nesting info
> From: Tian, Kevin > Sent: Tuesday, June 30, 2020 10:01 AM > > > From: Liu, Yi L > > Sent: Monday, June 29, 2020 8:23 PM > > > > Hi Stefan, > > > > > From: Stefan Hajnoczi > > > Sent: Monday, June 29, 2020 5:25 PM > > > > > > On Wed, Jun 24, 2020 at 01:55:15AM -0700, Liu Yi L wrote: > > > > +/* > > > > + * struct iommu_nesting_info - Information for nesting-capable IOMMU. > > > > + * user space should check it before using > > > > + * nesting capability. > > > > + * > > > > + * @size: size of the whole structure > > > > + * @format:PASID table entry format, the same definition with > > > > + * @format of struct iommu_gpasid_bind_data. > > > > + * @features: supported nesting features. > > > > + * @flags: currently reserved for future extension. > > > > + * @data: vendor specific cap info. > > > > + * > > > > + * > > > > +---++ > > > > + * | feature | Notes > > > > | > > > > + * > > > > > +===+=== > > > > > =+ > > > > + * | SYSWIDE_PASID | Kernel manages PASID in system wide, PASIDs > > used | > > > > + * | | in the system should be allocated by host kernel > > > > | > > > > + * > > > > +---++ > > > > + * | BIND_PGTBL| bind page tables to host PASID, the PASID could > > > > | > > > > + * | | either be a host PASID passed in bind request or > > > > | > > > > + * | | default PASIDs (e.g. default PASID of > > > > aux-domain) | > > > > + * > > > > +---++ > > > > + * | CACHE_INVLD | mandatory feature for nesting capable IOMMU > > | > > > > + * > > > > +---++ > > > > > > This feature description is vague about what CACHE_INVLD does and how > > to > > > use it. If I understand correctly, the presence of this feature means > > > that VFIO_IOMMU_NESTING_OP_CACHE_INVLD must be used? > > > > > > The same kind of clarification could be done for SYSWIDE_PASID and > > > BIND_PGTBL too. > > > > For SYSWIDE_PASID and BIND_PGTBL, yes, presence of the feature bit > > means must use. So the two are requirements to user space if it wants > > to setup nesting. While for CACHE_INVLD, it's kind of availability > > here. How about removing CACHE_INVLD as presence of BIND_PGTBL should > > indicates support of CACHE_INVLD? > > > > So far this assumption is correct but it may not be true when thinking > forward. > For example, a vendor might find a way to allow the owner of 1st-level page > table to directly invalidate cache w/o going through host IOMMU driver. From > this angle I feel explicitly reporting this capability is more robust. I see. explicitly require 1st-level page table owner to do cache invalidation after modifying page table is fair to me. > Regarding to the description, what about below? > > -- > SYSWIDE_PASID: PASIDs are managed in system-wide, instead of per device. > When a device is assigned to userspace or VM, proper uAPI (provided by > userspace driver framework, e.g. VFIO) must be used to allocate/free PASIDs > for the assigned device. > > BIND_PGTBL: The owner of the first-level/stage-1 page table must explicitly > bind the page table to associated PASID (either the one specified in bind > request or the default PASID of the iommu domain), through VFIO_IOMMU > _NESTING_OP > > CACHE_INVLD: The owner of the first-level/stage-1 page table must > explicitly invalidate the IOMMU cache through VFIO_IOMMU_NESTING_OP, > according to vendor-specific requirement when changing the page table. > -- thanks for the statements, will apply. Regards, Yi Liu > Thanks > Kevin > >
RE: [PATCH v3 02/14] iommu: Report domain nesting info
> From: Liu, Yi L > Sent: Monday, June 29, 2020 8:23 PM > > Hi Stefan, > > > From: Stefan Hajnoczi > > Sent: Monday, June 29, 2020 5:25 PM > > > > On Wed, Jun 24, 2020 at 01:55:15AM -0700, Liu Yi L wrote: > > > +/* > > > + * struct iommu_nesting_info - Information for nesting-capable IOMMU. > > > + * user space should check it before using > > > + * nesting capability. > > > + * > > > + * @size:size of the whole structure > > > + * @format: PASID table entry format, the same definition with > > > + * @format of struct iommu_gpasid_bind_data. > > > + * @features:supported nesting features. > > > + * @flags: currently reserved for future extension. > > > + * @data:vendor specific cap info. > > > + * > > > + * +---++ > > > + * | feature | Notes | > > > + * > > > +===+=== > > > =+ > > > + * | SYSWIDE_PASID | Kernel manages PASID in system wide, PASIDs > used | > > > + * | | in the system should be allocated by host kernel | > > > + * +---++ > > > + * | BIND_PGTBL| bind page tables to host PASID, the PASID could | > > > + * | | either be a host PASID passed in bind request or | > > > + * | | default PASIDs (e.g. default PASID of aux-domain) | > > > + * +---++ > > > + * | CACHE_INVLD | mandatory feature for nesting capable IOMMU > | > > > + * +---++ > > > > This feature description is vague about what CACHE_INVLD does and how > to > > use it. If I understand correctly, the presence of this feature means > > that VFIO_IOMMU_NESTING_OP_CACHE_INVLD must be used? > > > > The same kind of clarification could be done for SYSWIDE_PASID and > > BIND_PGTBL too. > > For SYSWIDE_PASID and BIND_PGTBL, yes, presence of the feature bit > means must use. So the two are requirements to user space if it wants > to setup nesting. While for CACHE_INVLD, it's kind of availability > here. How about removing CACHE_INVLD as presence of BIND_PGTBL should > indicates support of CACHE_INVLD? > So far this assumption is correct but it may not be true when thinking forward. For example, a vendor might find a way to allow the owner of 1st-level page table to directly invalidate cache w/o going through host IOMMU driver. From this angle I feel explicitly reporting this capability is more robust. Regarding to the description, what about below? -- SYSWIDE_PASID: PASIDs are managed in system-wide, instead of per device. When a device is assigned to userspace or VM, proper uAPI (provided by userspace driver framework, e.g. VFIO) must be used to allocate/free PASIDs for the assigned device. BIND_PGTBL: The owner of the first-level/stage-1 page table must explicitly bind the page table to associated PASID (either the one specified in bind request or the default PASID of the iommu domain), through VFIO_IOMMU _NESTING_OP CACHE_INVLD: The owner of the first-level/stage-1 page table must explicitly invalidate the IOMMU cache through VFIO_IOMMU_NESTING_OP, according to vendor-specific requirement when changing the page table. -- Thanks Kevin
RE: [PATCH v3 02/14] iommu: Report domain nesting info
> From: Liu, Yi L > Sent: Saturday, June 27, 2020 2:53 PM > > Hi Robin, > > > From: Robin Murphy > > Sent: Saturday, June 27, 2020 12:05 AM > > > > On 2020-06-26 08:47, Jean-Philippe Brucker wrote: > > > On Wed, Jun 24, 2020 at 01:55:15AM -0700, Liu Yi L wrote: > > >> IOMMUs that support nesting translation needs report the capability > > >> info to userspace, e.g. the format of first level/stage paging > > >> structures. > > >> > > >> This patch reports nesting info by DOMAIN_ATTR_NESTING. Caller can > > >> get nesting info after setting DOMAIN_ATTR_NESTING. > > >> > > >> v2 -> v3: > > >> *) remvoe cap/ecap_mask in iommu_nesting_info. > > >> *) reuse DOMAIN_ATTR_NESTING to get nesting info. > > >> *) return an empty iommu_nesting_info for SMMU drivers per Jean' > > >> suggestion. > > >> > > >> Cc: Kevin Tian > > >> CC: Jacob Pan > > >> Cc: Alex Williamson > > >> Cc: Eric Auger > > >> Cc: Jean-Philippe Brucker > > >> Cc: Joerg Roedel > > >> Cc: Lu Baolu > > >> Signed-off-by: Liu Yi L > > >> Signed-off-by: Jacob Pan > > >> --- > > >> drivers/iommu/arm-smmu-v3.c | 29 -- > > >> drivers/iommu/arm-smmu.c| 29 -- > > > > > > Looks reasonable to me. Please move the SMMU changes to a separate > > > patch and Cc the SMMU maintainers: > > > > Cheers Jean, I'll admit I've been skipping over a lot of these patches > > lately :) > > > > A couple of comments below... > > > > > > > > Cc: Will Deacon > > > Cc: Robin Murphy > > > > > > Thanks, > > > Jean > > > > > >> include/uapi/linux/iommu.h | 59 > > + > > >> 3 files changed, 113 insertions(+), 4 deletions(-) > > >> > > >> diff --git a/drivers/iommu/arm-smmu-v3.c > > >> b/drivers/iommu/arm-smmu-v3.c index f578677..0c45d4d 100644 > > >> --- a/drivers/iommu/arm-smmu-v3.c > > >> +++ b/drivers/iommu/arm-smmu-v3.c > > >> @@ -3019,6 +3019,32 @@ static struct iommu_group > > *arm_smmu_device_group(struct device *dev) > > >> return group; > > >> } > > >> > > >> +static int arm_smmu_domain_nesting_info(struct arm_smmu_domain > > *smmu_domain, > > >> +void *data) > > >> +{ > > >> +struct iommu_nesting_info *info = (struct iommu_nesting_info *) > data; > > >> +u32 size; > > >> + > > >> +if (!info || smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED) > > >> +return -ENODEV; > > >> + > > >> +size = sizeof(struct iommu_nesting_info); > > >> + > > >> +/* > > >> + * if provided buffer size is not equal to the size, should > > >> + * return 0 and also the expected buffer size to caller. > > >> + */ > > >> +if (info->size != size) { > > >> +info->size = size; > > >> +return 0; > > >> +} > > >> + > > >> +/* report an empty iommu_nesting_info for now */ > > >> +memset(info, 0x0, size); > > >> +info->size = size; > > >> +return 0; > > >> +} > > >> + > > >> static int arm_smmu_domain_get_attr(struct iommu_domain *domain, > > >> enum iommu_attr attr, void *data) > > >> { > > >> @@ -3028,8 +3054,7 @@ static int arm_smmu_domain_get_attr(struct > > iommu_domain *domain, > > >> case IOMMU_DOMAIN_UNMANAGED: > > >> switch (attr) { > > >> case DOMAIN_ATTR_NESTING: > > >> -*(int *)data = (smmu_domain->stage == > > ARM_SMMU_DOMAIN_NESTED); > > >> -return 0; > > >> +return > arm_smmu_domain_nesting_info(smmu_domain, > > data); > > >> default: > > >> return -ENODEV; > > >> } > > >> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c > > >> index 243bc4c..908607d 100644 > > >> --- a/drivers/iommu/arm-smmu.c > > >> +++ b/drivers/iommu/arm-smmu.c > > >> @@ -1506,6 +1506,32 @@ static struct iommu_group > > *arm_smmu_device_group(struct device *dev) > > >> return group; > > >> } > > >> > > >> +static int arm_smmu_domain_nesting_info(struct arm_smmu_domain > > *smmu_domain, > > >> +void *data) > > >> +{ > > >> +struct iommu_nesting_info *info = (struct iommu_nesting_info *) > data; > > >> +u32 size; > > >> + > > >> +if (!info || smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED) > > >> +return -ENODEV; > > >> + > > >> +size = sizeof(struct iommu_nesting_info); > > >> + > > >> +/* > > >> + * if provided buffer size is not equal to the size, should > > >> + * return 0 and also the expected buffer size to caller. > > >> + */ > > >> +if (info->size != size) { > > >> +info->size = size; > > >> +return 0; > > >> +} > > >> + > > >> +/* report an empty iommu_nesting_info for now */ > > >> +
Re: [PATCH v3 02/14] iommu: Report domain nesting info
On Wed, Jun 24, 2020 at 01:55:15AM -0700, Liu Yi L wrote: > +/* > + * struct iommu_nesting_info - Information for nesting-capable IOMMU. > + * user space should check it before using > + * nesting capability. > + * > + * @size:size of the whole structure > + * @format: PASID table entry format, the same definition with > + * @format of struct iommu_gpasid_bind_data. > + * @features:supported nesting features. > + * @flags: currently reserved for future extension. > + * @data:vendor specific cap info. > + * > + * +---++ > + * | feature | Notes | > + * +===++ > + * | SYSWIDE_PASID | Kernel manages PASID in system wide, PASIDs used | > + * | | in the system should be allocated by host kernel | > + * +---++ > + * | BIND_PGTBL| bind page tables to host PASID, the PASID could | > + * | | either be a host PASID passed in bind request or | > + * | | default PASIDs (e.g. default PASID of aux-domain) | > + * +---++ > + * | CACHE_INVLD | mandatory feature for nesting capable IOMMU | > + * +---++ This feature description is vague about what CACHE_INVLD does and how to use it. If I understand correctly, the presence of this feature means that VFIO_IOMMU_NESTING_OP_CACHE_INVLD must be used? The same kind of clarification could be done for SYSWIDE_PASID and BIND_PGTBL too. Stefan signature.asc Description: PGP signature
RE: [PATCH v3 02/14] iommu: Report domain nesting info
Hi Stefan, > From: Stefan Hajnoczi > Sent: Monday, June 29, 2020 5:25 PM > > On Wed, Jun 24, 2020 at 01:55:15AM -0700, Liu Yi L wrote: > > +/* > > + * struct iommu_nesting_info - Information for nesting-capable IOMMU. > > + * user space should check it before using > > + * nesting capability. > > + * > > + * @size: size of the whole structure > > + * @format:PASID table entry format, the same definition with > > + * @format of struct iommu_gpasid_bind_data. > > + * @features: supported nesting features. > > + * @flags: currently reserved for future extension. > > + * @data: vendor specific cap info. > > + * > > + * +---++ > > + * | feature | Notes | > > + * > +===+=== > =+ > > + * | SYSWIDE_PASID | Kernel manages PASID in system wide, PASIDs used | > > + * | | in the system should be allocated by host kernel | > > + * +---++ > > + * | BIND_PGTBL| bind page tables to host PASID, the PASID could | > > + * | | either be a host PASID passed in bind request or | > > + * | | default PASIDs (e.g. default PASID of aux-domain) | > > + * +---++ > > + * | CACHE_INVLD | mandatory feature for nesting capable IOMMU | > > + * +---++ > > This feature description is vague about what CACHE_INVLD does and how to > use it. If I understand correctly, the presence of this feature means > that VFIO_IOMMU_NESTING_OP_CACHE_INVLD must be used? > > The same kind of clarification could be done for SYSWIDE_PASID and > BIND_PGTBL too. For SYSWIDE_PASID and BIND_PGTBL, yes, presence of the feature bit means must use. So the two are requirements to user space if it wants to setup nesting. While for CACHE_INVLD, it's kind of availability here. How about removing CACHE_INVLD as presence of BIND_PGTBL should indicates support of CACHE_INVLD? Regards, Yi Liu > Stefan
RE: [PATCH v3 02/14] iommu: Report domain nesting info
Hi Robin, > From: Robin Murphy > Sent: Saturday, June 27, 2020 12:05 AM > > On 2020-06-26 08:47, Jean-Philippe Brucker wrote: > > On Wed, Jun 24, 2020 at 01:55:15AM -0700, Liu Yi L wrote: > >> IOMMUs that support nesting translation needs report the capability > >> info to userspace, e.g. the format of first level/stage paging structures. > >> > >> This patch reports nesting info by DOMAIN_ATTR_NESTING. Caller can > >> get nesting info after setting DOMAIN_ATTR_NESTING. > >> > >> v2 -> v3: > >> *) remvoe cap/ecap_mask in iommu_nesting_info. > >> *) reuse DOMAIN_ATTR_NESTING to get nesting info. > >> *) return an empty iommu_nesting_info for SMMU drivers per Jean' > >> suggestion. > >> > >> Cc: Kevin Tian > >> CC: Jacob Pan > >> Cc: Alex Williamson > >> Cc: Eric Auger > >> Cc: Jean-Philippe Brucker > >> Cc: Joerg Roedel > >> Cc: Lu Baolu > >> Signed-off-by: Liu Yi L > >> Signed-off-by: Jacob Pan > >> --- > >> drivers/iommu/arm-smmu-v3.c | 29 -- > >> drivers/iommu/arm-smmu.c| 29 -- > > > > Looks reasonable to me. Please move the SMMU changes to a separate > > patch and Cc the SMMU maintainers: > > Cheers Jean, I'll admit I've been skipping over a lot of these patches lately > :) > > A couple of comments below... > > > > > Cc: Will Deacon > > Cc: Robin Murphy > > > > Thanks, > > Jean > > > >> include/uapi/linux/iommu.h | 59 > + > >> 3 files changed, 113 insertions(+), 4 deletions(-) > >> > >> diff --git a/drivers/iommu/arm-smmu-v3.c > >> b/drivers/iommu/arm-smmu-v3.c index f578677..0c45d4d 100644 > >> --- a/drivers/iommu/arm-smmu-v3.c > >> +++ b/drivers/iommu/arm-smmu-v3.c > >> @@ -3019,6 +3019,32 @@ static struct iommu_group > *arm_smmu_device_group(struct device *dev) > >>return group; > >> } > >> > >> +static int arm_smmu_domain_nesting_info(struct arm_smmu_domain > *smmu_domain, > >> + void *data) > >> +{ > >> + struct iommu_nesting_info *info = (struct iommu_nesting_info *) data; > >> + u32 size; > >> + > >> + if (!info || smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED) > >> + return -ENODEV; > >> + > >> + size = sizeof(struct iommu_nesting_info); > >> + > >> + /* > >> + * if provided buffer size is not equal to the size, should > >> + * return 0 and also the expected buffer size to caller. > >> + */ > >> + if (info->size != size) { > >> + info->size = size; > >> + return 0; > >> + } > >> + > >> + /* report an empty iommu_nesting_info for now */ > >> + memset(info, 0x0, size); > >> + info->size = size; > >> + return 0; > >> +} > >> + > >> static int arm_smmu_domain_get_attr(struct iommu_domain *domain, > >>enum iommu_attr attr, void *data) > >> { > >> @@ -3028,8 +3054,7 @@ static int arm_smmu_domain_get_attr(struct > iommu_domain *domain, > >>case IOMMU_DOMAIN_UNMANAGED: > >>switch (attr) { > >>case DOMAIN_ATTR_NESTING: > >> - *(int *)data = (smmu_domain->stage == > ARM_SMMU_DOMAIN_NESTED); > >> - return 0; > >> + return arm_smmu_domain_nesting_info(smmu_domain, > data); > >>default: > >>return -ENODEV; > >>} > >> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c > >> index 243bc4c..908607d 100644 > >> --- a/drivers/iommu/arm-smmu.c > >> +++ b/drivers/iommu/arm-smmu.c > >> @@ -1506,6 +1506,32 @@ static struct iommu_group > *arm_smmu_device_group(struct device *dev) > >>return group; > >> } > >> > >> +static int arm_smmu_domain_nesting_info(struct arm_smmu_domain > *smmu_domain, > >> + void *data) > >> +{ > >> + struct iommu_nesting_info *info = (struct iommu_nesting_info *) data; > >> + u32 size; > >> + > >> + if (!info || smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED) > >> + return -ENODEV; > >> + > >> + size = sizeof(struct iommu_nesting_info); > >> + > >> + /* > >> + * if provided buffer size is not equal to the size, should > >> + * return 0 and also the expected buffer size to caller. > >> + */ > >> + if (info->size != size) { > >> + info->size = size; > >> + return 0; > >> + } > >> + > >> + /* report an empty iommu_nesting_info for now */ > >> + memset(info, 0x0, size); > >> + info->size = size; > >> + return 0; > >> +} > >> + > >> static int arm_smmu_domain_get_attr(struct iommu_domain *domain, > >>enum iommu_attr attr, void *data) > >> { > >> @@ -1515,8 +1541,7 @@ static int arm_smmu_domain_get_attr(struct > iommu_domain *domain, > >>case IOMMU_DOMAIN_UNMANAGED: > >>switch (attr) { > >>case DOMAIN_ATTR_NESTING: > >> - *(int *)data = (smmu_domain->stage == > ARM_SMMU_DOMAIN_NESTED); > >> - return 0; > >> + return
RE: [PATCH v3 02/14] iommu: Report domain nesting info
> From: Jean-Philippe Brucker > Sent: Friday, June 26, 2020 3:48 PM > > On Wed, Jun 24, 2020 at 01:55:15AM -0700, Liu Yi L wrote: > > IOMMUs that support nesting translation needs report the capability > > info to userspace, e.g. the format of first level/stage paging structures. > > > > This patch reports nesting info by DOMAIN_ATTR_NESTING. Caller can get > > nesting info after setting DOMAIN_ATTR_NESTING. > > > > v2 -> v3: > > *) remvoe cap/ecap_mask in iommu_nesting_info. > > *) reuse DOMAIN_ATTR_NESTING to get nesting info. > > *) return an empty iommu_nesting_info for SMMU drivers per Jean' > >suggestion. > > > > Cc: Kevin Tian > > CC: Jacob Pan > > Cc: Alex Williamson > > Cc: Eric Auger > > Cc: Jean-Philippe Brucker > > Cc: Joerg Roedel > > Cc: Lu Baolu > > Signed-off-by: Liu Yi L > > Signed-off-by: Jacob Pan > > --- > > drivers/iommu/arm-smmu-v3.c | 29 -- > > drivers/iommu/arm-smmu.c| 29 -- > > Looks reasonable to me. Please move the SMMU changes to a separate patch > and Cc the SMMU maintainers: > > Cc: Will Deacon > Cc: Robin Murphy got you. will do it. Regards, Yi Liu > Thanks, > Jean > > > include/uapi/linux/iommu.h | 59 > > + > > 3 files changed, 113 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c > > index f578677..0c45d4d 100644 > > --- a/drivers/iommu/arm-smmu-v3.c > > +++ b/drivers/iommu/arm-smmu-v3.c > > @@ -3019,6 +3019,32 @@ static struct iommu_group > *arm_smmu_device_group(struct device *dev) > > return group; > > } > > > > +static int arm_smmu_domain_nesting_info(struct arm_smmu_domain > *smmu_domain, > > + void *data) > > +{ > > + struct iommu_nesting_info *info = (struct iommu_nesting_info *) data; > > + u32 size; > > + > > + if (!info || smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED) > > + return -ENODEV; > > + > > + size = sizeof(struct iommu_nesting_info); > > + > > + /* > > +* if provided buffer size is not equal to the size, should > > +* return 0 and also the expected buffer size to caller. > > +*/ > > + if (info->size != size) { > > + info->size = size; > > + return 0; > > + } > > + > > + /* report an empty iommu_nesting_info for now */ > > + memset(info, 0x0, size); > > + info->size = size; > > + return 0; > > +} > > + > > static int arm_smmu_domain_get_attr(struct iommu_domain *domain, > > enum iommu_attr attr, void *data) { @@ - > 3028,8 +3054,7 @@ > > static int arm_smmu_domain_get_attr(struct iommu_domain *domain, > > case IOMMU_DOMAIN_UNMANAGED: > > switch (attr) { > > case DOMAIN_ATTR_NESTING: > > - *(int *)data = (smmu_domain->stage == > ARM_SMMU_DOMAIN_NESTED); > > - return 0; > > + return arm_smmu_domain_nesting_info(smmu_domain, > data); > > default: > > return -ENODEV; > > } > > diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index > > 243bc4c..908607d 100644 > > --- a/drivers/iommu/arm-smmu.c > > +++ b/drivers/iommu/arm-smmu.c > > @@ -1506,6 +1506,32 @@ static struct iommu_group > *arm_smmu_device_group(struct device *dev) > > return group; > > } > > > > +static int arm_smmu_domain_nesting_info(struct arm_smmu_domain > *smmu_domain, > > + void *data) > > +{ > > + struct iommu_nesting_info *info = (struct iommu_nesting_info *) data; > > + u32 size; > > + > > + if (!info || smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED) > > + return -ENODEV; > > + > > + size = sizeof(struct iommu_nesting_info); > > + > > + /* > > +* if provided buffer size is not equal to the size, should > > +* return 0 and also the expected buffer size to caller. > > +*/ > > + if (info->size != size) { > > + info->size = size; > > + return 0; > > + } > > + > > + /* report an empty iommu_nesting_info for now */ > > + memset(info, 0x0, size); > > + info->size = size; > > + return 0; > > +} > > + > > static int arm_smmu_domain_get_attr(struct iommu_domain *domain, > > enum iommu_attr attr, void *data) { @@ - > 1515,8 +1541,7 @@ > > static int arm_smmu_domain_get_attr(struct iommu_domain *domain, > > case IOMMU_DOMAIN_UNMANAGED: > > switch (attr) { > > case DOMAIN_ATTR_NESTING: > > - *(int *)data = (smmu_domain->stage == > ARM_SMMU_DOMAIN_NESTED); > > - return 0; > > + return arm_smmu_domain_nesting_info(smmu_domain, > data); > > default: > > return -ENODEV; > > } > > diff --git a/include/uapi/linux/iommu.h b/include/uapi/linux/iommu.h > > index 1afc661..898c99a 100644 > > ---
Re: [PATCH v3 02/14] iommu: Report domain nesting info
On 2020-06-26 08:47, Jean-Philippe Brucker wrote: On Wed, Jun 24, 2020 at 01:55:15AM -0700, Liu Yi L wrote: IOMMUs that support nesting translation needs report the capability info to userspace, e.g. the format of first level/stage paging structures. This patch reports nesting info by DOMAIN_ATTR_NESTING. Caller can get nesting info after setting DOMAIN_ATTR_NESTING. v2 -> v3: *) remvoe cap/ecap_mask in iommu_nesting_info. *) reuse DOMAIN_ATTR_NESTING to get nesting info. *) return an empty iommu_nesting_info for SMMU drivers per Jean' suggestion. Cc: Kevin Tian CC: Jacob Pan Cc: Alex Williamson Cc: Eric Auger Cc: Jean-Philippe Brucker Cc: Joerg Roedel Cc: Lu Baolu Signed-off-by: Liu Yi L Signed-off-by: Jacob Pan --- drivers/iommu/arm-smmu-v3.c | 29 -- drivers/iommu/arm-smmu.c| 29 -- Looks reasonable to me. Please move the SMMU changes to a separate patch and Cc the SMMU maintainers: Cheers Jean, I'll admit I've been skipping over a lot of these patches lately :) A couple of comments below... Cc: Will Deacon Cc: Robin Murphy Thanks, Jean include/uapi/linux/iommu.h | 59 + 3 files changed, 113 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index f578677..0c45d4d 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -3019,6 +3019,32 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev) return group; } +static int arm_smmu_domain_nesting_info(struct arm_smmu_domain *smmu_domain, + void *data) +{ + struct iommu_nesting_info *info = (struct iommu_nesting_info *) data; + u32 size; + + if (!info || smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED) + return -ENODEV; + + size = sizeof(struct iommu_nesting_info); + + /* +* if provided buffer size is not equal to the size, should +* return 0 and also the expected buffer size to caller. +*/ + if (info->size != size) { + info->size = size; + return 0; + } + + /* report an empty iommu_nesting_info for now */ + memset(info, 0x0, size); + info->size = size; + return 0; +} + static int arm_smmu_domain_get_attr(struct iommu_domain *domain, enum iommu_attr attr, void *data) { @@ -3028,8 +3054,7 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, case IOMMU_DOMAIN_UNMANAGED: switch (attr) { case DOMAIN_ATTR_NESTING: - *(int *)data = (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED); - return 0; + return arm_smmu_domain_nesting_info(smmu_domain, data); default: return -ENODEV; } diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 243bc4c..908607d 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1506,6 +1506,32 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev) return group; } +static int arm_smmu_domain_nesting_info(struct arm_smmu_domain *smmu_domain, + void *data) +{ + struct iommu_nesting_info *info = (struct iommu_nesting_info *) data; + u32 size; + + if (!info || smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED) + return -ENODEV; + + size = sizeof(struct iommu_nesting_info); + + /* +* if provided buffer size is not equal to the size, should +* return 0 and also the expected buffer size to caller. +*/ + if (info->size != size) { + info->size = size; + return 0; + } + + /* report an empty iommu_nesting_info for now */ + memset(info, 0x0, size); + info->size = size; + return 0; +} + static int arm_smmu_domain_get_attr(struct iommu_domain *domain, enum iommu_attr attr, void *data) { @@ -1515,8 +1541,7 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, case IOMMU_DOMAIN_UNMANAGED: switch (attr) { case DOMAIN_ATTR_NESTING: - *(int *)data = (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED); - return 0; + return arm_smmu_domain_nesting_info(smmu_domain, data); default: return -ENODEV; } diff --git a/include/uapi/linux/iommu.h b/include/uapi/linux/iommu.h index 1afc661..898c99a 100644 --- a/include/uapi/linux/iommu.h +++ b/include/uapi/linux/iommu.h @@ -332,4 +332,63 @@ struct iommu_gpasid_bind_data { } vendor; }; +/* + * struct iommu_nesting_info - Information for nesting-capable IOMMU. + *
Re: [PATCH v3 02/14] iommu: Report domain nesting info
On Wed, Jun 24, 2020 at 01:55:15AM -0700, Liu Yi L wrote: > IOMMUs that support nesting translation needs report the capability info > to userspace, e.g. the format of first level/stage paging structures. > > This patch reports nesting info by DOMAIN_ATTR_NESTING. Caller can get > nesting info after setting DOMAIN_ATTR_NESTING. > > v2 -> v3: > *) remvoe cap/ecap_mask in iommu_nesting_info. > *) reuse DOMAIN_ATTR_NESTING to get nesting info. > *) return an empty iommu_nesting_info for SMMU drivers per Jean' >suggestion. > > Cc: Kevin Tian > CC: Jacob Pan > Cc: Alex Williamson > Cc: Eric Auger > Cc: Jean-Philippe Brucker > Cc: Joerg Roedel > Cc: Lu Baolu > Signed-off-by: Liu Yi L > Signed-off-by: Jacob Pan > --- > drivers/iommu/arm-smmu-v3.c | 29 -- > drivers/iommu/arm-smmu.c| 29 -- Looks reasonable to me. Please move the SMMU changes to a separate patch and Cc the SMMU maintainers: Cc: Will Deacon Cc: Robin Murphy Thanks, Jean > include/uapi/linux/iommu.h | 59 > + > 3 files changed, 113 insertions(+), 4 deletions(-) > > diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c > index f578677..0c45d4d 100644 > --- a/drivers/iommu/arm-smmu-v3.c > +++ b/drivers/iommu/arm-smmu-v3.c > @@ -3019,6 +3019,32 @@ static struct iommu_group > *arm_smmu_device_group(struct device *dev) > return group; > } > > +static int arm_smmu_domain_nesting_info(struct arm_smmu_domain *smmu_domain, > + void *data) > +{ > + struct iommu_nesting_info *info = (struct iommu_nesting_info *) data; > + u32 size; > + > + if (!info || smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED) > + return -ENODEV; > + > + size = sizeof(struct iommu_nesting_info); > + > + /* > + * if provided buffer size is not equal to the size, should > + * return 0 and also the expected buffer size to caller. > + */ > + if (info->size != size) { > + info->size = size; > + return 0; > + } > + > + /* report an empty iommu_nesting_info for now */ > + memset(info, 0x0, size); > + info->size = size; > + return 0; > +} > + > static int arm_smmu_domain_get_attr(struct iommu_domain *domain, > enum iommu_attr attr, void *data) > { > @@ -3028,8 +3054,7 @@ static int arm_smmu_domain_get_attr(struct iommu_domain > *domain, > case IOMMU_DOMAIN_UNMANAGED: > switch (attr) { > case DOMAIN_ATTR_NESTING: > - *(int *)data = (smmu_domain->stage == > ARM_SMMU_DOMAIN_NESTED); > - return 0; > + return arm_smmu_domain_nesting_info(smmu_domain, data); > default: > return -ENODEV; > } > diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c > index 243bc4c..908607d 100644 > --- a/drivers/iommu/arm-smmu.c > +++ b/drivers/iommu/arm-smmu.c > @@ -1506,6 +1506,32 @@ static struct iommu_group > *arm_smmu_device_group(struct device *dev) > return group; > } > > +static int arm_smmu_domain_nesting_info(struct arm_smmu_domain *smmu_domain, > + void *data) > +{ > + struct iommu_nesting_info *info = (struct iommu_nesting_info *) data; > + u32 size; > + > + if (!info || smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED) > + return -ENODEV; > + > + size = sizeof(struct iommu_nesting_info); > + > + /* > + * if provided buffer size is not equal to the size, should > + * return 0 and also the expected buffer size to caller. > + */ > + if (info->size != size) { > + info->size = size; > + return 0; > + } > + > + /* report an empty iommu_nesting_info for now */ > + memset(info, 0x0, size); > + info->size = size; > + return 0; > +} > + > static int arm_smmu_domain_get_attr(struct iommu_domain *domain, > enum iommu_attr attr, void *data) > { > @@ -1515,8 +1541,7 @@ static int arm_smmu_domain_get_attr(struct iommu_domain > *domain, > case IOMMU_DOMAIN_UNMANAGED: > switch (attr) { > case DOMAIN_ATTR_NESTING: > - *(int *)data = (smmu_domain->stage == > ARM_SMMU_DOMAIN_NESTED); > - return 0; > + return arm_smmu_domain_nesting_info(smmu_domain, data); > default: > return -ENODEV; > } > diff --git a/include/uapi/linux/iommu.h b/include/uapi/linux/iommu.h > index 1afc661..898c99a 100644 > --- a/include/uapi/linux/iommu.h > +++ b/include/uapi/linux/iommu.h > @@ -332,4 +332,63 @@ struct iommu_gpasid_bind_data { > } vendor; > }; > > +/* > + * struct iommu_nesting_info - Information for nesting-capable IOMMU. > + * user space
[PATCH v3 02/14] iommu: Report domain nesting info
IOMMUs that support nesting translation needs report the capability info to userspace, e.g. the format of first level/stage paging structures. This patch reports nesting info by DOMAIN_ATTR_NESTING. Caller can get nesting info after setting DOMAIN_ATTR_NESTING. v2 -> v3: *) remvoe cap/ecap_mask in iommu_nesting_info. *) reuse DOMAIN_ATTR_NESTING to get nesting info. *) return an empty iommu_nesting_info for SMMU drivers per Jean' suggestion. Cc: Kevin Tian CC: Jacob Pan Cc: Alex Williamson Cc: Eric Auger Cc: Jean-Philippe Brucker Cc: Joerg Roedel Cc: Lu Baolu Signed-off-by: Liu Yi L Signed-off-by: Jacob Pan --- drivers/iommu/arm-smmu-v3.c | 29 -- drivers/iommu/arm-smmu.c| 29 -- include/uapi/linux/iommu.h | 59 + 3 files changed, 113 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index f578677..0c45d4d 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -3019,6 +3019,32 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev) return group; } +static int arm_smmu_domain_nesting_info(struct arm_smmu_domain *smmu_domain, + void *data) +{ + struct iommu_nesting_info *info = (struct iommu_nesting_info *) data; + u32 size; + + if (!info || smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED) + return -ENODEV; + + size = sizeof(struct iommu_nesting_info); + + /* +* if provided buffer size is not equal to the size, should +* return 0 and also the expected buffer size to caller. +*/ + if (info->size != size) { + info->size = size; + return 0; + } + + /* report an empty iommu_nesting_info for now */ + memset(info, 0x0, size); + info->size = size; + return 0; +} + static int arm_smmu_domain_get_attr(struct iommu_domain *domain, enum iommu_attr attr, void *data) { @@ -3028,8 +3054,7 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, case IOMMU_DOMAIN_UNMANAGED: switch (attr) { case DOMAIN_ATTR_NESTING: - *(int *)data = (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED); - return 0; + return arm_smmu_domain_nesting_info(smmu_domain, data); default: return -ENODEV; } diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 243bc4c..908607d 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1506,6 +1506,32 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev) return group; } +static int arm_smmu_domain_nesting_info(struct arm_smmu_domain *smmu_domain, + void *data) +{ + struct iommu_nesting_info *info = (struct iommu_nesting_info *) data; + u32 size; + + if (!info || smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED) + return -ENODEV; + + size = sizeof(struct iommu_nesting_info); + + /* +* if provided buffer size is not equal to the size, should +* return 0 and also the expected buffer size to caller. +*/ + if (info->size != size) { + info->size = size; + return 0; + } + + /* report an empty iommu_nesting_info for now */ + memset(info, 0x0, size); + info->size = size; + return 0; +} + static int arm_smmu_domain_get_attr(struct iommu_domain *domain, enum iommu_attr attr, void *data) { @@ -1515,8 +1541,7 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, case IOMMU_DOMAIN_UNMANAGED: switch (attr) { case DOMAIN_ATTR_NESTING: - *(int *)data = (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED); - return 0; + return arm_smmu_domain_nesting_info(smmu_domain, data); default: return -ENODEV; } diff --git a/include/uapi/linux/iommu.h b/include/uapi/linux/iommu.h index 1afc661..898c99a 100644 --- a/include/uapi/linux/iommu.h +++ b/include/uapi/linux/iommu.h @@ -332,4 +332,63 @@ struct iommu_gpasid_bind_data { } vendor; }; +/* + * struct iommu_nesting_info - Information for nesting-capable IOMMU. + * user space should check it before using + * nesting capability. + * + * @size: size of the whole structure + * @format:PASID table entry format, the same definition with + * @format of struct iommu_gpasid_bind_data. + * @features: supported nesting features. + * @flags: currently reserved for future extension. + * @data: