Commit 129938f5 authored by Xingang Wang's avatar Xingang Wang Committed by Yang Yingliang
Browse files

iommu/arm-smmu-v3: Add support to enable/disable SMMU user_mpam_en

ascend inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I49RB2


CVE: NA

-------------------------------------------------

The user_mpam_en configuration is used to enable/disable
whether SMMU mpam configuration will be used. If user_mpam_en
is 1, the memory requests across SMMU will not carry the
SMMU mpam configuration.

Signed-off-by: default avatarXingang Wang <wangxingang5@huawei.com>
Reviewed-by: default avatarYingtai Xie <xieyingtai@huawei.com>
Reviewed-by: default avatarZhen Lei <thunder.leizhen@huawei.com>
Signed-off-by: default avatarYang Yingliang <yangyingliang@huawei.com>
parent 2b7032bc
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -194,6 +194,9 @@
#define MPAMIDR_PMG_MAX			GENMASK(23, 16)
#define MPAMIDR_PARTID_MAX		GENMASK(15, 0)

#define ARM_SMMU_USER_CFG0		0xe00
#define ARM_SMMU_USER_MPAM_EN		(1UL << 30)

/* Common MSI config fields */
#define MSI_CFG0_ADDR_MASK		GENMASK_ULL(51, 2)
#define MSI_CFG2_SH			GENMASK(5, 4)
@@ -4346,6 +4349,40 @@ int arm_smmu_get_dev_mpam(struct device *dev, int ssid, int *partid, int *pmg,
}
EXPORT_SYMBOL(arm_smmu_get_dev_mpam);

/**
 * arm_smmu_set_dev_user_mpam_en() - set user_mpam_en to smmu user cfg0
 */
int arm_smmu_set_dev_user_mpam_en(struct device *dev, int user_mpam_en)
{
	struct arm_smmu_master_data *master = dev->iommu_fwspec->iommu_priv;
	struct arm_smmu_device *smmu = master->domain->smmu;
	u32 reg, __iomem *cfg = smmu->base + ARM_SMMU_USER_CFG0;

	reg = readl_relaxed(cfg);
	reg &= ~ARM_SMMU_USER_MPAM_EN;
	reg |= FIELD_PREP(ARM_SMMU_USER_MPAM_EN, user_mpam_en);
	writel_relaxed(reg, cfg);

	return 0;
}
EXPORT_SYMBOL(arm_smmu_set_dev_user_mpam_en);

/**
 * arm_smmu_get_dev_user_mpam_en() - get user_mpam_en from smmu user cfg0
 */
int arm_smmu_get_dev_user_mpam_en(struct device *dev, int *user_mpam_en)
{
	struct arm_smmu_master_data *master = dev->iommu_fwspec->iommu_priv;
	struct arm_smmu_device *smmu = master->domain->smmu;
	u32 reg, __iomem *cfg = smmu->base + ARM_SMMU_USER_CFG0;

	reg = readl_relaxed(cfg);
	*user_mpam_en = FIELD_GET(ARM_SMMU_USER_MPAM_EN, reg);

	return 0;
}
EXPORT_SYMBOL(arm_smmu_get_dev_user_mpam_en);

static int arm_smmu_device_probe(struct platform_device *pdev)
{
	int irq, ret;
+3 −0
Original line number Diff line number Diff line
@@ -9,4 +9,7 @@ extern int arm_smmu_set_dev_mpam(struct device *dev, int ssid, int partid,
extern int arm_smmu_get_dev_mpam(struct device *dev, int ssid, int *partid,
		int *pmg, int *s1mpam);

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);

#endif /* __LINUX_ASCEND_SMMU_H */