When CPUs come online the original configuration should be restored.
Once the maximum partid is known, allocate an configuration array for each
component, and reprogram each RIS configuration from this.
The MPAM spec describes how multiple controls can interact. To prevent this
happening by accident, always reset controls that don't have a valid
configuration. This allows the same helper to be used for configuration and
reset.
diff --git a/drivers/platform/arm64/mpam/mpam_devices.c
b/drivers/platform/arm64/mpam/mpam_devices.c
index bb3695eb84e9..f3ecfda265d2 100644
--- a/drivers/platform/arm64/mpam/mpam_devices.c
+++ b/drivers/platform/arm64/mpam/mpam_devices.c
@@ -909,51 +913,90 @@ static void mpam_reset_msc_bitmap(struct
mpam_msc *msc, u16 reg, u16 wd)
__mpam_write_reg(msc, reg, bm);
}
-static void mpam_reset_ris_partid(struct mpam_msc_ris *ris, u16 partid)
+/* Called via IPI. Call while holding an SRCU reference */ static void
+mpam_reprogram_ris_partid(struct mpam_msc_ris *ris, u16 partid,
+ struct mpam_config *cfg)
{
u16 bwa_fract = MPAMCFG_MBW_MAX_MAX;
struct mpam_msc *msc = ris->vmsc->msc;
struct mpam_props *rprops = &ris->props;
- mpam_assert_srcu_read_lock_held();
-
mutex_lock(&msc->part_sel_lock);
__mpam_part_sel(ris->ris_idx, partid, msc);
- if (mpam_has_feature(mpam_feat_cpor_part, rprops))
- mpam_reset_msc_bitmap(msc, MPAMCFG_CPBM,
rprops->cpbm_wd);
+ if (mpam_has_feature(mpam_feat_cpor_part, rprops)) {
+ if (mpam_has_feature(mpam_feat_cpor_part, cfg))
+ mpam_write_partsel_reg(msc, CPBM, cfg->cpbm);
+ else
+ mpam_reset_msc_bitmap(msc, MPAMCFG_CPBM,
+ rprops->cpbm_wd);
+ }
- if (mpam_has_feature(mpam_feat_mbw_part, rprops))
- mpam_reset_msc_bitmap(msc, MPAMCFG_MBW_PBM,
rprops->mbw_pbm_bits);
+ if (mpam_has_feature(mpam_feat_mbw_part, rprops)) {
+ if (mpam_has_feature(mpam_feat_mbw_part, cfg))
+ mpam_write_partsel_reg(msc, MBW_PBM,
cfg->mbw_pbm);
+ else
+ mpam_reset_msc_bitmap(msc,
MPAMCFG_MBW_PBM,
+ rprops->mbw_pbm_bits);
+ }
if (mpam_has_feature(mpam_feat_mbw_min, rprops))
mpam_write_partsel_reg(msc, MBW_MIN, 0);
- if (mpam_has_feature(mpam_feat_mbw_max, rprops))
- mpam_write_partsel_reg(msc, MBW_MAX, bwa_fract);
+ 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
+ mpam_write_partsel_reg(msc, MBW_MAX,
bwa_fract);
+ }
0 was written to MPAMCFG_MBW_MAX. [HARDLIM].
Depending on the chip, if [HARDLIM] is set to 1 by default, it will be overwritten.