From 80db6616c710a358391516ad82de44361580f8da Mon Sep 17 00:00:00 2001 From: Ben Horgan Date: Thu, 17 Sep 2026 15:56:10 +0100 Subject: [PATCH] arm_mpam: Ensure MBWU counters are reset on restore When an MSC becomes inaccessible due to cpu offline CFG_MBWU_CTL is set to zero in mpam_save_mbwu_state(). This is very likely to mean that the config will mismatch when restoring and so the monitor will be reset. However, the state may have been lost and so there are no guarantees. Ensure the reset happens by setting the reset_on_next_read and remove the unnecessary writes from mpam_save_mbwu_state(). Fixes: 41e8a14950e1 ("arm_mpam: Track bandwidth counter state for power management") Signed-off-by: Ben Horgan Tested-by: Gavin Shan Reviewed-by: Gavin Shan Reviewed-by: James Morse [morse: Restored clearing of CTL register for kexec/powerdown] Signed-off-by: James Morse --- drivers/resctrl/mpam_devices.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/resctrl/mpam_devices.c b/drivers/resctrl/mpam_devices.c index d39d210574a6..6df48bec82e2 100644 --- a/drivers/resctrl/mpam_devices.c +++ b/drivers/resctrl/mpam_devices.c @@ -1652,6 +1652,7 @@ static int mpam_restore_mbwu_state(void *_ris) u64 val; struct mon_read mwbu_arg; struct mpam_msc_ris *ris = _ris; + struct msmon_mbwu_state *mbwu_state; struct mpam_msc *msc = ris->vmsc->msc; struct mpam_class *class = ris->vmsc->comp->class; @@ -1659,16 +1660,20 @@ static int mpam_restore_mbwu_state(void *_ris) if (WARN_ON_ONCE(!mpam_mon_sel_lock(msc))) return -EIO; - if (!ris->mbwu_state[i].enabled) { + mbwu_state = &ris->mbwu_state[i]; + + if (!mbwu_state->enabled) { mpam_mon_sel_unlock(msc); continue; } mwbu_arg.ris = ris; - mwbu_arg.ctx = &ris->mbwu_state[i].cfg; + mwbu_arg.ctx = &mbwu_state->cfg; mwbu_arg.type = mpam_msmon_choose_counter(class); mwbu_arg.val = &val; + mbwu_state->reset_on_next_read = true; + mpam_mon_sel_unlock(msc); __ris_msmon_read(&mwbu_arg); @@ -1703,13 +1708,10 @@ static int mpam_save_mbwu_state(void *arg) cur_ctl = mpam_read_monsel_reg(msc, CFG_MBWU_CTL); mpam_write_monsel_reg(msc, CFG_MBWU_CTL, 0); - if (mpam_ris_has_mbwu_long_counter(ris)) { + if (mpam_ris_has_mbwu_long_counter(ris)) val = mpam_msc_read_mbwu_l(msc); - mpam_msc_zero_mbwu_l(msc); - } else { + else val = mpam_read_monsel_reg(msc, MBWU); - mpam_write_monsel_reg(msc, MBWU, 0); - } cfg->mon = i; cfg->pmg = FIELD_GET(MSMON_CFG_x_FLT_PMG, cur_flt);