Re: [RFC PATCH 33/36] arm_mpam: Use long MBWU counters if supported

From: James Morse
Date: Fri Aug 08 2025 - 03:30:07 EST


Hi Ben,

On 28/07/2025 14:46, Ben Horgan wrote:
On 7/11/25 19:36, James Morse wrote:
From: Rohit Mathew <rohit.mathew@xxxxxxx>

If the 44 bit (long) or 63 bit (LWD) counters are detected on probing
the RIS, use long/LWD counter instead of the regular 31 bit mbwu
counter.

Only 32bit accesses to the MSC are required to be supported by the
spec, but these registers are 64bits. The lower half may overflow
into the higher half between two 32bit reads. To avoid this, use
a helper that reads the top half twice to check for overflow.

Slightly misleading as it may be read up to 4 times.

Meh - its referring to the high/low/high pattern. Sure if it fails you go round the whole
thing again. I'll change it 'read multiple times to check for overflow'.


diff --git a/drivers/platform/arm64/mpam/mpam_devices.c b/drivers/platform/arm64/mpam/
mpam_devices.c
index 774137a124f8..ace69ac2d0ee 100644
--- a/drivers/platform/arm64/mpam/mpam_devices.c
+++ b/drivers/platform/arm64/mpam/mpam_devices.c
@@ -1125,10 +1177,24 @@ static void __ris_msmon_read(void *arg)
now = FIELD_GET(MSMON___VALUE, now);
break;
case mpam_feat_msmon_mbwu:
- now = mpam_read_monsel_reg(msc, MBWU);
- if (mpam_has_feature(mpam_feat_msmon_mbwu_hw_nrdy, rprops))
- nrdy = now & MSMON___NRDY;
- now = FIELD_GET(MSMON___VALUE, now);
+ /*
+ * If long or lwd counters are supported, use them, else revert
+ * to the 32 bit counter.
+ */
32 bit counter -> 31 bit counter

Sure,


+ if (mpam_ris_has_mbwu_long_counter(ris)) {
+ now = mpam_msc_read_mbwu_l(msc);
+ if (mpam_has_feature(mpam_feat_msmon_mbwu_hw_nrdy, rprops))
+ nrdy = now & MSMON___NRDY_L;
+ if (mpam_has_feature(mpam_feat_msmon_mbwu_63counter, rprops))
+ now = FIELD_GET(MSMON___LWD_VALUE, now);
+ else
+ now = FIELD_GET(MSMON___L_VALUE, now);
+ } else {
+ now = mpam_read_monsel_reg(msc, MBWU);
+ if (mpam_has_feature(mpam_feat_msmon_mbwu_hw_nrdy, rprops))
+ nrdy = now & MSMON___NRDY;
+ now = FIELD_GET(MSMON___VALUE, now);
+ }
if (nrdy)
break;

diff --git a/drivers/platform/arm64/mpam/mpam_internal.h b/drivers/platform/arm64/mpam/
mpam_internal.h
index fc705801c1b6..4553616f2f67 100644
--- a/drivers/platform/arm64/mpam/mpam_internal.h
+++ b/drivers/platform/arm64/mpam/mpam_internal.h
@@ -674,7 +675,10 @@ int mpam_get_cpumask_from_cache_id(unsigned long cache_id, u32
cache_level,
*/
#define MSMON___VALUE GENMASK(30, 0)
#define MSMON___NRDY BIT(31)
-#define MSMON_MBWU_L_VALUE GENMASK(62, 0)
+#define MSMON___NRDY_L BIT(63)
+#define MSMON___L_VALUE GENMASK(43, 0)
+#define MSMON___LWD_VALUE GENMASK(62, 0)
+
As mentioned on an earlier patch. These could be added with all the other register
definition.

Yup,


Thanks,

James