lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <20250117151033.1517882-24-Dave.Martin@arm.com>
Date: Fri, 17 Jan 2025 15:10:33 +0000
From: Dave Martin <Dave.Martin@....com>
To: linux-kernel@...r.kernel.org
Cc: linux-arm-kernel@...ts.infradead.org,
	Zeng Heng <zengheng4@...wei.com>,
	Shaopeng Tan <tan.shaopeng@...itsu.com>,
	James Morse <james.morse@....com>
Subject: [RFC PATCH v2 11/11] arm_mpam: Detect whether the system can alias PARTIDs

In order to be able to assign multiple PARTIDs freely to resource
control groups, it is necessary that all MSCs that are used by resctrl
either implement PARTID Narrowing (so that PARTIDs can be remapped
explicitly) or otherwise only have controls whose resource regulation
is stateless and so whose behaviour would not be affected by splitting
a control group across multiple PARTIDs.

Detect this property at the RIS level and merge it up the MPAM devices
tree.

Export the common global result as mpam_partid_aliasing, and apply
it to the PARTIDs-per-CLOSID configuration.

Signed-off-by: Dave Martin <Dave.Martin@....com>

---

Currently, this the logic is simple and may forbid PARTID aliasing
on some systems that can support it as a result of the precise set
of MSCs and controls that are exposed through resctrl.

The aim is to make this logic more flexible later.
---
 drivers/platform/arm64/mpam/mpam_devices.c  | 48 ++++++++++++++++++---
 drivers/platform/arm64/mpam/mpam_internal.h |  2 +
 drivers/platform/arm64/mpam/mpam_resctrl.c  | 12 +++++-
 3 files changed, 53 insertions(+), 9 deletions(-)

diff --git a/drivers/platform/arm64/mpam/mpam_devices.c b/drivers/platform/arm64/mpam/mpam_devices.c
index 4b43dfef1cdc..0182c922638f 100644
--- a/drivers/platform/arm64/mpam/mpam_devices.c
+++ b/drivers/platform/arm64/mpam/mpam_devices.c
@@ -68,6 +68,7 @@ static DEFINE_MUTEX(mpam_cpuhp_state_lock);
  */
 u16 mpam_partid_max;
 u8 mpam_pmg_max;
+bool mpam_partid_aliasing; /* PARTID aliasing supported */
 static bool partid_max_init, partid_max_published;
 static DEFINE_SPINLOCK(partid_max_lock);
 
@@ -828,6 +829,7 @@ static void mpam_ris_hw_probe(struct mpam_msc_ris *ris)
 	struct mpam_msc *msc = ris->vmsc->msc;
 	struct mpam_props *props = &ris->props;
 	struct mpam_class *class = ris->vmsc->comp->class;
+	bool partid_can_alias = true;
 
 	lockdep_assert_held(&msc->probe_lock);
 	lockdep_assert_held(&msc->part_sel_lock);
@@ -836,6 +838,8 @@ static void mpam_ris_hw_probe(struct mpam_msc_ris *ris)
 
 	/* Cache Capacity Partitioning */
 	if (FIELD_GET(MPAMF_IDR_HAS_CCAP_PART, ris->idr)) {
+		partid_can_alias = false;
+
 		ris->ccap_idr = mpam_read_partsel_reg(msc, CCAP_IDR);
 
 		props->cmax_wd = FIELD_GET(MPAMF_CCAP_IDR_CMAX_WD, ris->ccap_idr);
@@ -884,14 +888,20 @@ static void mpam_ris_hw_probe(struct mpam_msc_ris *ris)
 		 */
 		props->bwa_wd = min(props->bwa_wd, 16);
 
-		if (props->bwa_wd && FIELD_GET(MPAMF_MBW_IDR_HAS_MAX, mbw_features))
+		if (props->bwa_wd && FIELD_GET(MPAMF_MBW_IDR_HAS_MAX, mbw_features)) {
 			mpam_set_feature(mpam_feat_mbw_max, props);
+			partid_can_alias = false;
+		}
 
-		if (props->bwa_wd && FIELD_GET(MPAMF_MBW_IDR_HAS_MIN, mbw_features))
+		if (props->bwa_wd && FIELD_GET(MPAMF_MBW_IDR_HAS_MIN, mbw_features)) {
 			mpam_set_feature(mpam_feat_mbw_min, props);
+			partid_can_alias = false;
+		}
 
-		if (props->bwa_wd && FIELD_GET(MPAMF_MBW_IDR_HAS_PROP, mbw_features))
+		if (props->bwa_wd && FIELD_GET(MPAMF_MBW_IDR_HAS_PROP, mbw_features)) {
 			mpam_set_feature(mpam_feat_mbw_prop, props);
+			partid_can_alias = false;
+		}
 	}
 
 	/* Priority partitioning */
@@ -988,17 +998,26 @@ static void mpam_ris_hw_probe(struct mpam_msc_ris *ris)
 	 * RIS with PARTID narrowing don't have enough storage for one
 	 * configuration per PARTID. If these are in a class we could use,
 	 * reduce the supported partid_max to match the numer of intpartid.
-	 * If the class is unknown, just ignore it.
+	 * If the MSC won't be used for anything or implements PARTID
+	 * Narrowing then PARTIDs can be assigned freely, so PARTID
+	 * aliasing can be supported regardless of the resource
+	 * controls present.
 	 */
-	if (FIELD_GET(MPAMF_IDR_HAS_PARTID_NRW, ris->idr) &&
-	    class->type != MPAM_CLASS_UNKNOWN) {
+	if (class->type == MPAM_CLASS_UNKNOWN)
+		partid_can_alias = true;
+	else if (FIELD_GET(MPAMF_IDR_HAS_PARTID_NRW, ris->idr)) {
 		u32 nrwidr = mpam_read_partsel_reg(msc, PARTID_NRW_IDR);
 		u16 partid_max = FIELD_GET(MPAMF_PARTID_NRW_IDR_INTPARTID_MAX, nrwidr);
 
 		mpam_set_feature(mpam_feat_partid_nrw, props);
 		msc->partid_max = min(msc->partid_max, partid_max);
+
+		partid_can_alias = true;
 	}
 
+	if (partid_can_alias)
+		mpam_set_feature(mpam_feat_partid_aliasing, props);
+
 	mpam_mon_sel_outer_unlock(msc);
 }
 
@@ -2368,6 +2387,10 @@ static void __props_mismatch(struct mpam_props *parent,
 		mpam_clear_feature(mpam_feat_dspri_part_0_low, &parent->features);
 	}
 
+	/* PARTID aliasing must be supported everywhere, or not at all: */
+	if (!mpam_has_feature(mpam_feat_partid_aliasing, parent))
+		mpam_clear_feature(mpam_feat_partid_aliasing, &parent->features);
+
 	if (alias) {
 		/* Merge features for aliased resources */
 		parent->features |= child->features;
@@ -2486,6 +2509,7 @@ static void mpam_enable_merge_features(struct list_head *all_classes_list)
 {
 	struct mpam_class *class;
 	struct mpam_component *comp;
+	bool partid_can_alias = true, comp_partid_aliasing;
 
 	lockdep_assert_held(&mpam_list_lock);
 
@@ -2495,9 +2519,19 @@ static void mpam_enable_merge_features(struct list_head *all_classes_list)
 
 		mpam_enable_init_class_features(class);
 
-		list_for_each_entry(comp, &class->components, class_list)
+		list_for_each_entry(comp, &class->components, class_list) {
 			mpam_enable_merge_class_features(comp);
+
+			comp_partid_aliasing = mpam_has_feature(
+				mpam_feat_partid_aliasing, &class->props);
+			partid_can_alias = partid_can_alias &&
+				comp_partid_aliasing;
+		}
 	}
+
+	spin_lock(&partid_max_lock);
+	mpam_partid_aliasing = partid_can_alias;
+	spin_unlock(&partid_max_lock);
 }
 
 static char *mpam_errcode_names[16] = {
diff --git a/drivers/platform/arm64/mpam/mpam_internal.h b/drivers/platform/arm64/mpam/mpam_internal.h
index 965f4fea3012..6e10e4789506 100644
--- a/drivers/platform/arm64/mpam/mpam_internal.h
+++ b/drivers/platform/arm64/mpam/mpam_internal.h
@@ -215,6 +215,7 @@ enum mpam_device_features {
 	mpam_feat_msmon_mbwu_hw_nrdy,
 	mpam_feat_msmon_capt,
 	mpam_feat_partid_nrw,
+	mpam_feat_partid_aliasing, /* derived feature */
 	MPAM_FEATURE_LAST,
 };
 #define MPAM_ALL_FEATURES      ((1<<MPAM_FEATURE_LAST) - 1)
@@ -474,6 +475,7 @@ static inline void mpam_assert_srcu_read_lock_held(void)
 /* System wide partid/pmg values */
 extern u16 mpam_partid_max;
 extern u8 mpam_pmg_max;
+extern bool mpam_partid_aliasing;
 
 /* Scheduled work callback to enable mpam once all MSC have been probed */
 void mpam_enable(struct work_struct *work);
diff --git a/drivers/platform/arm64/mpam/mpam_resctrl.c b/drivers/platform/arm64/mpam/mpam_resctrl.c
index 1f31b1455f66..5b296e3e27c2 100644
--- a/drivers/platform/arm64/mpam/mpam_resctrl.c
+++ b/drivers/platform/arm64/mpam/mpam_resctrl.c
@@ -160,7 +160,8 @@ static bool mpam_resctrl_hide_cdp(enum resctrl_res_level rid)
 	return cdp_enabled && !resctrl_arch_get_cdp_enabled(rid);
 }
 
-static unsigned int partid_per_closid = 1;
+static unsigned int bootparam_partid_per_closid = 1;
+static unsigned int partid_per_closid;
 
 static int mpam_resctrl_partid_per_closid_set(const char *val,
 					      const struct kernel_param *kp)
@@ -178,7 +179,7 @@ static const struct kernel_param_ops mpam_resctrl_partid_per_closid_ops  = {
 };
 
 device_param_cb(partid_per_closid, &mpam_resctrl_partid_per_closid_ops,
-		&partid_per_closid, 0444);
+		&bootparam_partid_per_closid, 0444);
 
 static unsigned int mpam_num_pmg(void)
 {
@@ -1113,6 +1114,13 @@ int mpam_resctrl_setup(void)
 	if (!err && !exposed_alloc_capable && !exposed_mon_capable)
 		err = -EOPNOTSUPP;
 
+	partid_per_closid = bootparam_partid_per_closid;
+	if ((!mpam_partid_aliasing && bootparam_partid_per_closid > 1) ||
+	    resctrl_arch_get_num_closid(NULL) < 1) {
+		pr_warn("Hardware incompatible with PARTID aliasing, limiting monitoring groups\n");
+		partid_per_closid = 1;
+	}
+
 	if (!err) {
 		err = resctrl_init();
 		if (!err)
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ