From: Xingang Wang wangxingang5@huawei.com
ascend inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4L735 CVE: NA
-------------------------------------------------
This introduce support to set and get device configuration in iommu private driver. For example, when the smmu mpam configuration need to be set in the smmu driver, these interfaces will help.
Signed-off-by: Xingang Wang wangxingang5@huawei.com Reviewed-by: Zhen Lei thunder.leizhen@huawei.com Reviewed-by: Weilong Chen chenweilong@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 18 +++++++++++++++++ drivers/iommu/iommu.c | 22 +++++++++++++++++++++ include/linux/iommu.h | 18 +++++++++++++++++ 3 files changed, 58 insertions(+)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index b9b2232b6b83..be4b66ccdd05 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -4081,6 +4081,22 @@ static int arm_smmu_device_domain_type(struct device *dev) } #endif
+static int arm_smmu_device_get_config(struct device *dev, int type, void *data) +{ + switch (type) { + default: + return -EINVAL; + } +} + +static int arm_smmu_device_set_config(struct device *dev, int type, void *data) +{ + switch (type) { + default: + return -EINVAL; + } +} + static struct iommu_ops arm_smmu_ops = { .capable = arm_smmu_capable, .domain_alloc = arm_smmu_domain_alloc, @@ -4122,6 +4138,8 @@ static struct iommu_ops arm_smmu_ops = { #ifdef CONFIG_SMMU_BYPASS_DEV .def_domain_type = arm_smmu_device_domain_type, #endif + .dev_get_config = arm_smmu_device_get_config, + .dev_set_config = arm_smmu_device_set_config, .pgsize_bitmap = -1UL, /* Restricted during device attach */ };
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 9adb9d2502ae..25b3b8386ca9 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -3567,3 +3567,25 @@ u32 iommu_sva_get_pasid(struct iommu_sva *handle) return ops->sva_get_pasid(handle); } EXPORT_SYMBOL_GPL(iommu_sva_get_pasid); + +int iommu_dev_set_config(struct device *dev, int type, void *data) +{ + const struct iommu_ops *ops = dev->bus->iommu_ops; + + if (ops && ops->dev_set_config) + return ops->dev_set_config(dev, type, data); + + return -ENODEV; +} +EXPORT_SYMBOL_GPL(iommu_dev_set_config); + +int iommu_dev_get_config(struct device *dev, int type, void *data) +{ + const struct iommu_ops *ops = dev->bus->iommu_ops; + + if (ops && ops->dev_get_config) + return ops->dev_get_config(dev, type, data); + + return -ENODEV; +} +EXPORT_SYMBOL_GPL(iommu_dev_get_config); diff --git a/include/linux/iommu.h b/include/linux/iommu.h index d899e7a5f234..ed12f5cac0b4 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -348,6 +348,9 @@ struct iommu_ops { dma_addr_t giova, phys_addr_t gpa, size_t size); void (*unbind_guest_msi)(struct iommu_domain *domain, dma_addr_t giova);
+ int (*dev_get_config)(struct device *dev, int type, void *data); + int (*dev_set_config)(struct device *dev, int type, void *data); + unsigned long pgsize_bitmap; struct module *owner; }; @@ -584,6 +587,9 @@ extern int iommu_clear_dirty_log(struct iommu_domain *domain, unsigned long iova unsigned long base_iova, unsigned long bitmap_pgshift);
+extern int iommu_dev_set_config(struct device *dev, int type, void *data); +extern int iommu_dev_get_config(struct device *dev, int type, void *data); + /* Window handling function prototypes */ extern int iommu_domain_window_enable(struct iommu_domain *domain, u32 wnd_nr, phys_addr_t offset, u64 size, @@ -1215,6 +1221,18 @@ int iommu_bind_guest_msi(struct iommu_domain *domain, static inline void iommu_unbind_guest_msi(struct iommu_domain *domain, dma_addr_t giova) {}
+static inline +int iommu_dev_set_config(struct device *dev, int type, void *data) +{ + return -ENODEV; +} + +static inline +int iommmu_dev_get_config(struct device *dev, int type, void *data) +{ + return -ENODEV; +} + #endif /* CONFIG_IOMMU_API */
/**