diff --git a/drivers/platform/mpam/Kconfig b/drivers/platform/mpam/Kconfig
index 75f5b2454fbe45b9531e6a680ecdc55df166200b..96dd7c091a9fc2d1d377f91bfb2140cdb4511696 100644
--- a/drivers/platform/mpam/Kconfig
+++ b/drivers/platform/mpam/Kconfig
@@ -6,3 +6,4 @@ config ARM_CPU_RESCTRL
 	depends on ARM64 && ARCH_HAS_CPU_RESCTRL
 	depends on MISC_FILESYSTEMS
 	select RESCTRL_RMID_DEPENDS_ON_CLOSID
+	select RESCTRL_IOMMU if ARM_SMMU_V3
diff --git a/drivers/platform/mpam/mpam_resctrl.c b/drivers/platform/mpam/mpam_resctrl.c
index 7bf0186de65751acb3d0fe19a73fb6e80578217a..60de4b0927bf94a94cacb74811b36637ceb3b6e9 100644
--- a/drivers/platform/mpam/mpam_resctrl.c
+++ b/drivers/platform/mpam/mpam_resctrl.c
@@ -8,6 +8,7 @@
 #include <linux/cpu.h>
 #include <linux/cpumask.h>
 #include <linux/errno.h>
+#include <linux/iommu.h>
 #include <linux/limits.h>
 #include <linux/list.h>
 #include <linux/printk.h>
@@ -212,6 +213,67 @@ bool resctrl_arch_match_rmid(struct task_struct *tsk, u32 closid, u32 rmid)
 	return (tsk_closid == closid) && (tsk_rmid == rmid);
 }
 
+int resctrl_arch_set_iommu_closid_rmid(struct iommu_group *group, u32 closid,
+					u32 rmid)
+{
+	u16 partid;
+	const struct iommu_ops *ops;
+
+	ops = iommu_group_get_ops(group);
+	if (!ops || !ops->set_group_qos_params)
+		return -EOPNOTSUPP;
+
+	if (cdp_enabled)
+		partid = closid << 1;
+	else
+		partid = closid;
+
+	return ops->set_group_qos_params(group, partid, rmid);
+}
+
+bool resctrl_arch_match_iommu_closid(struct iommu_group *group, u32 closid)
+{
+	u16 partid;
+	int err = -EINVAL;
+	const struct iommu_ops *ops;
+
+	ops = iommu_group_get_ops(group);
+	if (!ops || !ops->get_group_qos_params)
+		return false;
+
+	err = ops->get_group_qos_params(group, &partid, NULL);
+	if (err)
+		return false;
+
+	if (cdp_enabled)
+		partid >>= 1;
+
+	return (partid == closid);
+}
+
+bool resctrl_arch_match_iommu_closid_rmid(struct iommu_group *group,
+					  u32 closid, u32 rmid)
+{
+	u8 pmg;
+	u16 partid;
+	int err = -EINVAL;
+	const struct iommu_ops *ops;
+
+	ops = iommu_group_get_ops(group);
+	if (!ops || !ops->get_group_qos_params)
+		return false;
+
+	err = ops->get_group_qos_params(group, &partid, &pmg);
+	if (err)
+		return false;
+
+	if (cdp_enabled)
+		partid >>= 1;
+
+	return (partid == closid) && (rmid == pmg);
+}
+
+
 struct rdt_resource *resctrl_arch_get_resource(enum resctrl_res_level l)
 {
 	if (l >= RDT_NUM_RESOURCES)
diff --git a/include/linux/arm_mpam.h b/include/linux/arm_mpam.h
index 3e3215223d79a490dfcdaeda963cf010f8fa0552..6d861ec69ce3ab5e45a737e2b5df8de6a579ae8e 100644
--- a/include/linux/arm_mpam.h
+++ b/include/linux/arm_mpam.h
@@ -82,6 +82,12 @@ struct rdt_resource;
 int resctrl_arch_mon_ctx_alloc_no_wait(struct rdt_resource *r, int evtid);
 void resctrl_arch_mon_ctx_free(struct rdt_resource *r, int evtid, int ctx);
 
+int resctrl_arch_set_iommu_closid_rmid(struct iommu_group *group, u32 closid,
+				       u32 rmid);
+bool resctrl_arch_match_iommu_closid(struct iommu_group *group, u32 closid);
+bool resctrl_arch_match_iommu_closid_rmid(struct iommu_group *group, u32 closid,
+					  u32 rmid);
+
 /* Pseudo lock is not supported by MPAM */
 static inline int resctrl_arch_pseudo_lock_fn(void *_plr) { return 0; }
 static inline int resctrl_arch_measure_l2_residency(void *_plr) { return 0; }