From: Xingang Wang wangxingang5@huawei.com
ascend inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I49RB2 CVE: NA
-------------------------------------------------
This add interface to get mpam configuration of accelarators managed by svm. The svm mpam get interface traverse all accelrators, and if all succeed, return the last successful result.
Signed-off-by: Xingang Wang wangxingang5@huawei.com Reviewed-by: Yingtai Xie xieyingtai@huawei.com Reviewed-by: Ding Tianhong dingtianhong@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/char/svm.c | 85 +++++++++++++++++++++++++++++++++++++ include/linux/ascend_smmu.h | 2 + 2 files changed, 87 insertions(+)
diff --git a/drivers/char/svm.c b/drivers/char/svm.c index 71aecf22c7007..7134823500a22 100644 --- a/drivers/char/svm.c +++ b/drivers/char/svm.c @@ -32,6 +32,7 @@ #include <linux/sched/mm.h> #include <linux/msi.h> #include <linux/acpi.h> +#include <linux/ascend_smmu.h>
#define SVM_DEVICE_NAME "svm" #define ASID_SHIFT 48 @@ -72,8 +73,11 @@ struct svm_device { struct device *dev; phys_addr_t l2buff; unsigned long l2size; + struct list_head entry; };
+static LIST_HEAD(sdev_list); + struct svm_bind_process { pid_t vpid; u64 ttbr; @@ -124,6 +128,15 @@ struct meminfo { unsigned long hugetlbtotal; };
+struct svm_mpam { +#define SVM_GET_DEV_MPAM (1 << 0) + int flags; + int pasid; + int partid; + int pmg; + int s1mpam; +}; + static struct bus_type svm_bus_type = { .name = "svm_bus", }; @@ -1183,6 +1196,76 @@ int svm_get_pasid(pid_t vpid, int dev_id __maybe_unused) } EXPORT_SYMBOL_GPL(svm_get_pasid);
+static int svm_get_core_mpam(struct device *dev, void *data) +{ + int err = 0; + struct svm_mpam *mpam = data; + + if (mpam->flags & SVM_GET_DEV_MPAM) { + err = arm_smmu_get_dev_mpam(dev, mpam->pasid, &mpam->partid, + &mpam->pmg, &mpam->s1mpam); + if (err) { + dev_err(dev, "get mpam failed, %d\n", err); + return err; + } + } + + return err; +} + +int __svm_get_mpam(struct svm_mpam *mpam) +{ + int err = 0; +#ifdef CONFIG_ACPI + struct core_device *cdev = NULL; +#else + struct svm_device *sdev = NULL; +#endif +#ifdef CONFIG_ACPI + list_for_each_entry(cdev, &child_list, entry) { + err = svm_get_core_mpam(&cdev->dev, mpam); + if (err) + return err; + } +#else + list_for_each_entry(sdev, &sdev_list, entry) { + err = device_for_each_child(sdev->dev, mpam, svm_get_core_mpam); + if (err) + return err; + } +#endif + return 0; +} + +/** + * svm_get_mpam() - get smmu mpam configuration of core device + * @pasid: substream id + * @partid: pointer to partid + * @pmg: pointer to pmg + * @s1mpam: pointer to s1mpam + */ +int svm_get_mpam(int pasid, int *partid, int *pmg, int *s1mpam) +{ + int err = 0; + struct svm_mpam mpam; + + if (!partid || !pmg || !s1mpam) + return -EINVAL; + + mpam.flags = SVM_GET_DEV_MPAM, + mpam.pasid = pasid, + err = __svm_get_mpam(&mpam); + if (err) + return err; + + *partid = mpam.partid; + *pmg = mpam.pmg; + *s1mpam = mpam.s1mpam; + + return 0; +} +EXPORT_SYMBOL_GPL(svm_get_mpam); + static int svm_set_rc(unsigned long __user *arg) { unsigned long addr, size, rc; @@ -1792,6 +1875,7 @@ static int svm_device_probe(struct platform_device *pdev) if (sdev->miscdev.name == NULL) return -ENOMEM;
+ list_add(&sdev->entry, &sdev_list); dev_set_drvdata(dev, sdev); err = misc_register(&sdev->miscdev); if (err) { @@ -1840,6 +1924,7 @@ static int svm_device_remove(struct platform_device *pdev)
device_for_each_child(sdev->dev, NULL, svm_remove_core); misc_deregister(&sdev->miscdev); + list_del(&sdev->entry);
return 0; } diff --git a/include/linux/ascend_smmu.h b/include/linux/ascend_smmu.h index c52968e98944c..a6d2058599be5 100644 --- a/include/linux/ascend_smmu.h +++ b/include/linux/ascend_smmu.h @@ -12,4 +12,6 @@ extern int arm_smmu_get_dev_mpam(struct device *dev, int ssid, int *partid, extern int arm_smmu_set_dev_user_mpam_en(struct device *dev, int user_mpam_en); extern int arm_smmu_get_dev_user_mpam_en(struct device *dev, int *user_mpam_en);
+extern int svm_get_mpam(int pasid, int *partid, int *pmg, int *s1mpam); + #endif /* __LINUX_ASCEND_SMMU_H */