提交 156610f7 编写于 作者: X Xingang Wang 提交者: Zheng Zengkai

iommu/arm-smmu-v3: Add support to get SMMU mpam configuration

ascend inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I4L735
CVE: NA

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

Add interface to get mpam configuration of CD/STE context, use s1mpam
to indicate whether partid and pmg from CD or STE.
Signed-off-by: NXingang Wang <wangxingang5@huawei.com>
Reviewed-by: NZhen Lei <thunder.leizhen@huawei.com>
Reviewed-by: NWeilong Chen <chenweilong@huawei.com>
Acked-by: NXie XiuQi <xiexiuqi@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 ae86d53e
...@@ -4187,9 +4187,79 @@ static int arm_smmu_device_set_mpam(struct device *dev, ...@@ -4187,9 +4187,79 @@ static int arm_smmu_device_set_mpam(struct device *dev,
} }
static int arm_smmu_get_mpam(struct arm_smmu_device *smmu,
int sid, int ssid, int *partid, int *pmg, int *s1mpam)
{
struct arm_smmu_master *master = arm_smmu_find_master(smmu, sid);
struct arm_smmu_domain *domain = master ? master->domain : NULL;
u64 val;
__le64 *ste, *cd;
if (WARN_ON(!domain))
return -EINVAL;
if (WARN_ON(!domain->s1_cfg.set))
return -EINVAL;
if (WARN_ON(ssid >= (1 << domain->s1_cfg.s1cdmax)))
return -E2BIG;
if (!(smmu->features & ARM_SMMU_FEAT_MPAM))
return -ENODEV;
/* get ste ptr */
ste = arm_smmu_get_step_for_sid(smmu, sid);
val = le64_to_cpu(ste[4]);
*partid = FIELD_GET(STRTAB_STE_4_PARTID_MASK, val);
val = le64_to_cpu(ste[5]);
*pmg = FIELD_GET(STRTAB_STE_5_PMG_MASK, val);
val = le64_to_cpu(ste[1]);
*s1mpam = FIELD_GET(STRTAB_STE_1_S1MPAM, val);
/* return STE mpam configuration when s1mpam == 0 */
if (!(*s1mpam))
return 0;
/* get cd ptr */
cd = arm_smmu_get_cd_ptr(domain, ssid);
if (WARN_ON(!cd))
return -ENOMEM;
val = le64_to_cpu(cd[5]);
*partid = FIELD_GET(CTXDESC_CD_5_PARTID_MASK, val);
*pmg = FIELD_GET(CTXDESC_CD_5_PMG_MASK, val);
return 0;
}
static int arm_smmu_device_get_mpam(struct device *dev,
struct arm_smmu_mpam *mpam)
{
struct arm_smmu_master *master = dev_iommu_priv_get(dev);
int ret;
if (WARN_ON(!master) || WARN_ON(!mpam))
return -EINVAL;
if (mpam->flags & ARM_SMMU_DEV_GET_MPAM) {
ret = arm_smmu_get_mpam(master->domain->smmu,
master->streams->id,
mpam->pasid,
&mpam->partid,
&mpam->pmg,
&mpam->s1mpam);
if (ret < 0)
return ret;
}
return 0;
}
static int arm_smmu_device_get_config(struct device *dev, int type, void *data) static int arm_smmu_device_get_config(struct device *dev, int type, void *data)
{ {
switch (type) { switch (type) {
case ARM_SMMU_MPAM:
return arm_smmu_device_get_mpam(dev, data);
default: default:
return -EINVAL; return -EINVAL;
} }
......
...@@ -7,6 +7,7 @@ enum arm_smmu_device_config_type { ...@@ -7,6 +7,7 @@ enum arm_smmu_device_config_type {
struct arm_smmu_mpam { struct arm_smmu_mpam {
#define ARM_SMMU_DEV_SET_MPAM (1 << 0) #define ARM_SMMU_DEV_SET_MPAM (1 << 0)
#define ARM_SMMU_DEV_GET_MPAM (1 << 1)
int flags; int flags;
int pasid; int pasid;
int partid; int partid;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册