Message ID | bd56d93c18621104a0fa1b0de31e9b760b81b769.1666042872.git.nicolinc@nvidia.com (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
Series | Define EINVAL as device/domain incompatibility | expand |
On 2022/10/18 7:01, Nicolin Chen wrote: > Cases like VFIO wish to attach a device to an existing domain that was > not allocated specifically from the device. This raises a condition > where the IOMMU driver can fail the domain attach because the domain and > device are incompatible with each other. > > This is a soft failure that can be resolved by using a different domain. > > Provide a dedicated errno EINVAL from the IOMMU driver during attach that > the reason why the attach failed is because of domain incompatibility. > > VFIO can use this to know that the attach is a soft failure and it should > continue searching. Otherwise, the attach will be a hard failure and VFIO > will return the code to userspace. > > Update kdocs to add rules of return value to the attach_dev op and APIs. > > Suggested-by: Jason Gunthorpe <jgg@nvidia.com> > Reviewed-by: Kevin Tian <kevin.tian@intel.com> > Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> > Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> > --- > drivers/iommu/iommu.c | 24 ++++++++++++++++++++++++ > include/linux/iommu.h | 12 ++++++++++++ > 2 files changed, 36 insertions(+) > > diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c > index 4893c2429ca5..3c0c5d64bb50 100644 > --- a/drivers/iommu/iommu.c > +++ b/drivers/iommu/iommu.c > @@ -1949,6 +1949,18 @@ static int __iommu_attach_device(struct iommu_domain *domain, > return ret; > } > > +/** > + * iommu_attach_device - Attach an IOMMU domain to a device > + * @domain: IOMMU domain to attach > + * @dev: Device that will be attached > + * > + * Returns 0 on success and error code on failure > + * > + * Note that EINVAL can be treated as a soft failure, indicating > + * that certain configuration of the domain is incompatible with > + * the device. In this case attaching a different domain to the > + * device may succeed. > + */ > int iommu_attach_device(struct iommu_domain *domain, struct device *dev) > { > struct iommu_group *group; > @@ -2075,6 +2087,18 @@ static int __iommu_attach_group(struct iommu_domain *domain, > return ret; > } > > +/** > + * iommu_attach_group - Attach an IOMMU domain to an IOMMU group > + * @domain: IOMMU domain to attach > + * @group: IOMMU group that will be attached > + * > + * Returns 0 on success and error code on failure > + * > + * Note that EINVAL can be treated as a soft failure, indicating > + * that certain configuration of the domain is incompatible with > + * the group. In this case attaching a different domain to the > + * group may succeed. > + */ > int iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group) > { > int ret; > diff --git a/include/linux/iommu.h b/include/linux/iommu.h > index a325532aeab5..6f3569340e8a 100644 > --- a/include/linux/iommu.h > +++ b/include/linux/iommu.h > @@ -266,6 +266,18 @@ struct iommu_ops { > /** > * struct iommu_domain_ops - domain specific operations > * @attach_dev: attach an iommu domain to a device > + * Return: > + * * 0 - success > + * * EINVAL - can indicate that device and domain are incompatible due to > + * some previous configuration of the domain, in which case the > + * driver shouldn't log an error, since it is legitimate for a > + * caller to test reuse of existing domains. Otherwise, it may > + * still represent some other fundamental problem > + * * ENOMEM - out of memory > + * * ENOSPC - non-ENOMEM type of resource allocation failures > + * * EBUSY - device is attached to a domain and cannot be changed > + * * ENODEV - device specific errors, not able to be attached > + * * <others> - treated as ENODEV by the caller. Use is discouraged > * @detach_dev: detach an iommu domain from a device > * @map: map a physically contiguous memory region to an iommu domain > * @map_pages: map a physically contiguous set of pages of the same size to Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com> Best regards, baolu
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 4893c2429ca5..3c0c5d64bb50 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -1949,6 +1949,18 @@ static int __iommu_attach_device(struct iommu_domain *domain, return ret; } +/** + * iommu_attach_device - Attach an IOMMU domain to a device + * @domain: IOMMU domain to attach + * @dev: Device that will be attached + * + * Returns 0 on success and error code on failure + * + * Note that EINVAL can be treated as a soft failure, indicating + * that certain configuration of the domain is incompatible with + * the device. In this case attaching a different domain to the + * device may succeed. + */ int iommu_attach_device(struct iommu_domain *domain, struct device *dev) { struct iommu_group *group; @@ -2075,6 +2087,18 @@ static int __iommu_attach_group(struct iommu_domain *domain, return ret; } +/** + * iommu_attach_group - Attach an IOMMU domain to an IOMMU group + * @domain: IOMMU domain to attach + * @group: IOMMU group that will be attached + * + * Returns 0 on success and error code on failure + * + * Note that EINVAL can be treated as a soft failure, indicating + * that certain configuration of the domain is incompatible with + * the group. In this case attaching a different domain to the + * group may succeed. + */ int iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group) { int ret; diff --git a/include/linux/iommu.h b/include/linux/iommu.h index a325532aeab5..6f3569340e8a 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -266,6 +266,18 @@ struct iommu_ops { /** * struct iommu_domain_ops - domain specific operations * @attach_dev: attach an iommu domain to a device + * Return: + * * 0 - success + * * EINVAL - can indicate that device and domain are incompatible due to + * some previous configuration of the domain, in which case the + * driver shouldn't log an error, since it is legitimate for a + * caller to test reuse of existing domains. Otherwise, it may + * still represent some other fundamental problem + * * ENOMEM - out of memory + * * ENOSPC - non-ENOMEM type of resource allocation failures + * * EBUSY - device is attached to a domain and cannot be changed + * * ENODEV - device specific errors, not able to be attached + * * <others> - treated as ENODEV by the caller. Use is discouraged * @detach_dev: detach an iommu domain from a device * @map: map a physically contiguous memory region to an iommu domain * @map_pages: map a physically contiguous set of pages of the same size to