[PATCH RFC v1 3/6] arm_mpam: resctrl: track MBW max hard-limit in config
From: Fenghua Yu
Date: Mon Nov 09 2026 - 16:34:39 EST
Once userspace sets MB_MAXHLM schemata, the driver must program the
HARDLIM bit in MPAMCFG_MBW_MAX. Without tracking the per-domain hard-
limit state in mpam_config, bandwidth reprogramming would ignore the
schemata and leave hard limits unchanged in hardware.
Add mbw_max_hardlim to mpam_config and set MPAMCFG_MBW_MAX bit 31
(HARDLIM) when reprogramming MBW_MAX on hardware that supports hard
limiting.
Signed-off-by: Fenghua Yu <fenghuay@xxxxxxxxxx>
---
drivers/resctrl/mpam_devices.c | 27 ++++++++++++++++++++++++---
drivers/resctrl/mpam_internal.h | 1 +
2 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/drivers/resctrl/mpam_devices.c b/drivers/resctrl/mpam_devices.c
index 1e56e8f3858e..7dee6617b134 100644
--- a/drivers/resctrl/mpam_devices.c
+++ b/drivers/resctrl/mpam_devices.c
@@ -1664,10 +1664,29 @@ static void mpam_reprogram_ris_partid(struct mpam_msc_ris *ris, u16 partid,
}
if (mpam_has_feature(mpam_feat_mbw_max, rprops)) {
- if (mpam_has_feature(mpam_feat_mbw_max, cfg))
- mpam_write_partsel_reg(msc, MBW_MAX, cfg->mbw_max);
- else
+ if (mpam_has_feature(mpam_feat_mbw_max, cfg) ||
+ mpam_has_feature(mpam_feat_mbw_max_hardlim_rw, cfg)) {
+ u32 mbw_val;
+
+ /*
+ * HARDLIM shares MPAMCFG_MBW_MAX with the bandwidth
+ * field. A hard-limit update does not program
+ * bandwidth: the shadow value is not live until an
+ * MB write, and reset leaves the register at
+ * MPAMCFG_MBW_MAX_MAX. Keep that programmed value.
+ */
+ if (mpam_has_feature(mpam_feat_mbw_max, cfg))
+ mbw_val = cfg->mbw_max;
+ else
+ mbw_val = MPAMCFG_MBW_MAX_MAX;
+
+ if (mpam_has_feature(mpam_feat_mbw_max_hardlim_rw, cfg) &&
+ cfg->mbw_max_hardlim)
+ mbw_val |= MPAMCFG_MBW_MAX_HARDLIM;
+ mpam_write_partsel_reg(msc, MBW_MAX, mbw_val);
+ } else {
mpam_write_partsel_reg(msc, MBW_MAX, MPAMCFG_MBW_MAX_MAX);
+ }
}
if (mpam_has_feature(mpam_feat_mbw_prop, rprops))
@@ -2986,6 +3005,8 @@ static bool mpam_update_config(struct mpam_config *cfg,
maybe_update_config(cfg, mpam_feat_cpor_part, newcfg, cpbm, has_changes);
maybe_update_config(cfg, mpam_feat_mbw_part, newcfg, mbw_pbm, has_changes);
maybe_update_config(cfg, mpam_feat_mbw_max, newcfg, mbw_max, has_changes);
+ maybe_update_config(cfg, mpam_feat_mbw_max_hardlim_rw, newcfg,
+ mbw_max_hardlim, has_changes);
return has_changes;
}
diff --git a/drivers/resctrl/mpam_internal.h b/drivers/resctrl/mpam_internal.h
index 6be32b2cb0ab..59d04cb663da 100644
--- a/drivers/resctrl/mpam_internal.h
+++ b/drivers/resctrl/mpam_internal.h
@@ -324,6 +324,7 @@ struct mpam_config {
u32 cpbm;
u32 mbw_pbm;
u16 mbw_max;
+ bool mbw_max_hardlim;
struct mpam_garbage garbage;
};
--
2.53.0