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>] [day] [month] [year] [list]
Message-ID: <20250626095208.1008871-1-gshan@redhat.com>
Date: Thu, 26 Jun 2025 19:52:08 +1000
From: Gavin Shan <gshan@...hat.com>
To: linux-kernel@...r.kernel.org
Cc: james.morse@....com,
	sdonthineni@...dia.com,
	rohit.mathew@....com,
	carl@...amperecomputing.com,
	gshan@...hat.com,
	shan.gavin@...il.com
Subject: [PATCH MPAM 6.16.rc1] arm_mpam: Enforce to recalculate mbw_min on configuration

mpam_feat_mbw_max is exposed to user by resctrlfs, but mpam_feat_mbw_min
should be recalculated based on the maximal memory bandwidth in every
configuration, which has been missed unfortunately. When a new group is
created, the default and maximal memory bandwidth percentage (100%) is
configured, the configuration instance (struct mpam_config) on the stack
is updated, including the minimal and maximal memory bandwidth. It's
copied to the domain's configuration instance. On next time when user
tries to configure by writing 'schemata', the minimal memory bandwidth
isn't never recalculated because mpam_feat_mbw_min has been seen in the
configuration, which inherits from the domain's instance.

For example, the value of register MPAMCFG_MBW_MIN is never changed no
matter what configuration is set.

  # uname -r
  6.16.0-rc1-gavin
  # mount -tresctrl none /sys/fs/resctrl
  # mkdir -p /sys/fs/resctrl/test
  # cd /sys/fs/resctrl/test
  # echo "MB:1=2" > schemata
  MAPMF_MBW_IDR               00000c07
  MPAMCFG_MBW_MAX             000005ff
  MPAMCFG_MBW_MIN             0000f000
  # echo "MB:1=100" > schemata
  MAPMF_MBW_IDR               00000c07
  MPAMCFG_MBW_MAX             0000ffff
  MPAMCFG_MBW_MIN             0000f000

Fix the issue by enforcing the calculation of the minimal memory bandwidth
in very configuration. With this applied, The register MPAMCFG_MBW_MIN
is updated with the expected value in every configuration.

  # cd /sys/fs/resctrl/test
  # echo "MB:1=2" > schemata
  MAPMF_MBW_IDR               00000c07
  MPAMCFG_MBW_MAX             000005ff
  MPAMCFG_MBW_MIN             00000200
  # echo "MB:1=100" > schemata
  MAPMF_MBW_IDR               00000c07
  MPAMCFG_MBW_MAX             0000ffff
  MPAMCFG_MBW_MIN             0000f000

Fixes: 75f4101bb338 ("arm_mpam: Generate a configuration for min controls")
Signed-off-by: Gavin Shan <gshan@...hat.com>
---
Appliable to James Morse's latest MPAM branch
https://git.kernel.org/pub/scm/linux/kernel/git/morse/linux.git
(branch: mpam/snapshot/v6.16-rc1)
---
 drivers/platform/arm64/mpam/mpam_devices.c | 27 ++++++++++------------
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/drivers/platform/arm64/mpam/mpam_devices.c b/drivers/platform/arm64/mpam/mpam_devices.c
index df8730491de2..4845dcb8e601 100644
--- a/drivers/platform/arm64/mpam/mpam_devices.c
+++ b/drivers/platform/arm64/mpam/mpam_devices.c
@@ -3192,6 +3192,9 @@ static void mpam_extend_config(struct mpam_class *class, struct mpam_config *cfg
 	u16 min, min_hw_granule, delta;
 	u16 max_hw_value, res0_bits;
 
+	if (!mpam_has_feature(mpam_feat_mbw_max, cfg))
+		return;
+
 	/*
 	 * Calculate the values the 'min' control can hold.
 	 * e.g. on a platform with bwa_wd = 8, min_hw_granule is 0x00ff because
@@ -3211,23 +3214,17 @@ static void mpam_extend_config(struct mpam_class *class, struct mpam_config *cfg
 	 *
 	 * Resctrl can only configure the MAX.
 	 */
-	if (mpam_has_feature(mpam_feat_mbw_max, cfg) &&
-	    !mpam_has_feature(mpam_feat_mbw_min, cfg)) {
-		delta = ((5 * MPAMCFG_MBW_MAX_MAX) / 100) - 1;
-		if (cfg->mbw_max > delta)
-			min = cfg->mbw_max - delta;
-		else
-			min = 0;
+	delta = ((5 * MPAMCFG_MBW_MAX_MAX) / 100) - 1;
+	if (cfg->mbw_max > delta)
+		min = cfg->mbw_max - delta;
+	else
+		min = 0;
 
-		cfg->mbw_min = max(min, min_hw_granule);
-		mpam_set_feature(mpam_feat_mbw_min, cfg);
-	}
+	cfg->mbw_min = max(min, min_hw_granule);
+	mpam_set_feature(mpam_feat_mbw_min, cfg);
+	if (mpam_has_quirk(T241_FORCE_MBW_MIN_TO_ONE, class))
+		cfg->mbw_min = max(cfg->mbw_min, min_hw_granule + 1);
 
-	if (mpam_has_quirk(T241_FORCE_MBW_MIN_TO_ONE, class) &&
-	    cfg->mbw_min <= min_hw_granule) {
-		cfg->mbw_min = min_hw_granule + 1;
-		mpam_set_feature(mpam_feat_mbw_min, cfg);
-	}
 }
 
 /* TODO: split into write_config/sync_config */
-- 
2.49.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ