Commit 0cc88dd8 authored by Xingang Wang's avatar Xingang Wang Committed by Yang Yingliang
Browse files

svm: Add support to get svm mpam configuration

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: default avatarXingang Wang <wangxingang5@huawei.com>
Reviewed-by: default avatarYingtai Xie <xieyingtai@huawei.com>
Reviewed-by: default avatarDing Tianhong <dingtianhong@huawei.com>
Signed-off-by: default avatarYang Yingliang <yangyingliang@huawei.com>
parent 129938f5
Loading
Loading
Loading
Loading
+85 −0
Original line number Diff line number Diff line
@@ -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;
}
+2 −0
Original line number Diff line number Diff line
@@ -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 */