IOMMU UAPI can be extended in the future by adding new fields at the end of each user data structure. Since we use a unified UAPI version for compatibility checking, a lookup function is needed to find the correct user data size to copy from user.
This patch adds a helper function based on a 2D lookup with version and type as input arguments. Signed-off-by: Liu Yi L <[email protected]> Signed-off-by: Jacob Pan <[email protected]> --- drivers/iommu/iommu.c | 22 ++++++++++++++++++++++ include/linux/iommu.h | 6 ++++++ 2 files changed, 28 insertions(+) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 7dd51c5d2ba1..9e5de9abebdf 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -1696,6 +1696,28 @@ int iommu_sva_unbind_gpasid(struct iommu_domain *domain, struct device *dev, } EXPORT_SYMBOL_GPL(iommu_sva_unbind_gpasid); + +/** + * Maintain a UAPI version to user data structure size lookup for each + * API function types we support. e.g. bind guest pasid, cache invalidation. + * As data structures being extended with new members, the offsetofend() + * will identify the new sizes. + */ +const static int iommu_uapi_data_size[NR_IOMMU_UAPI_TYPE][IOMMU_UAPI_VERSION] = { + /* IOMMU_UAPI_BIND_GPASID */ + {offsetofend(struct iommu_gpasid_bind_data, vtd)}, + /* IOMMU_UAPI_CACHE_INVAL */ + {offsetofend(struct iommu_cache_invalidate_info, addr_info)}, + /* IOMMU_UAPI_PAGE_RESP */ + {offsetofend(struct iommu_page_response, code)}, +}; + +int iommu_uapi_get_data_size(int type, int version) +{ + return iommu_uapi_data_size[type][version - 1]; +} +EXPORT_SYMBOL_GPL(iommu_uapi_get_data_size); + 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 9718c109ea0a..416fe02160ba 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -500,6 +500,7 @@ extern int iommu_report_device_fault(struct device *dev, struct iommu_fault_event *evt); extern int iommu_page_response(struct device *dev, struct iommu_page_response *msg); +extern int iommu_uapi_get_data_size(int type, int version); extern int iommu_group_id(struct iommu_group *group); extern struct iommu_group *iommu_group_get_for_dev(struct device *dev); @@ -885,6 +886,11 @@ static inline int iommu_page_response(struct device *dev, return -ENODEV; } +static int iommu_uapi_get_data_size(int type, int version) +{ + return -ENODEV; +} + static inline int iommu_group_id(struct iommu_group *group) { return -ENODEV; -- 2.7.4 _______________________________________________ iommu mailing list [email protected] https://lists.linuxfoundation.org/mailman/listinfo/iommu
