From 8dfbb8460f25f9026e690c767bd70ba22ec899b0 Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Thu, 6 Nov 2025 15:46:09 +0800 Subject: [PATCH 1/2] fs/resctrl: Fix the L3 CMAX conversion mechanism hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ICXA3G -------------------------------- RDT formats the precision through bw_validate() during the validity check. But MPAM does not rely on such conversion, the CMAX interface converts percentages through percent_to_ca_max() and ca_max_to_percent(). So skip the conversion in bw_validate() to avoid loss of precision. Finally, percent_to_ca_max() and ca_max_to_percent() are restored to round up the user configuration to the required precision, avoiding to pass values smaller than the minimum threshold as parameters. Fixes: 9e0a8eb88dc7 ("arm64/mpam: Add quirk for cmax and cmin") Signed-off-by: Zeng Heng --- drivers/platform/mpam/mpam_resctrl.c | 7 ++++--- fs/resctrl/ctrlmondata.c | 6 +++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/platform/mpam/mpam_resctrl.c b/drivers/platform/mpam/mpam_resctrl.c index 34fcb03c1eeb..658ef77f676c 100644 --- a/drivers/platform/mpam/mpam_resctrl.c +++ b/drivers/platform/mpam/mpam_resctrl.c @@ -686,7 +686,7 @@ static u16 percent_to_mbw_max(u32 pc, u8 wd) static u16 percent_to_ca_max(u32 pc, u8 wd) { struct rdt_resource *l3 = resctrl_arch_get_resource(RDT_RESOURCE_L3); - u32 valid_max; + u32 valid_max, ca_max; if (read_cpuid_implementor() != ARM_CPU_IMP_HISI) return percent_to_mbw_max(pc, wd); @@ -698,7 +698,8 @@ static u16 percent_to_ca_max(u32 pc, u8 wd) if (pc >= MAX_MBA_BW) return valid_max << (16 - wd); - return ((pc * valid_max + 50) / 100) << (16 - wd); + ca_max = DIV_ROUND_UP(pc * valid_max, 100); + return ca_max << (16 - wd); } static u16 ca_max_to_percent(u16 ca_max, u8 wd) @@ -717,7 +718,7 @@ static u16 ca_max_to_percent(u16 ca_max, u8 wd) if (ca_max >= valid_max) return MAX_MBA_BW; - return (ca_max * 100 + valid_max / 2) / valid_max; + return (ca_max * 100) / valid_max; } /* Test whether we can export MPAM_CLASS_CACHE:{2,3}? */ diff --git a/fs/resctrl/ctrlmondata.c b/fs/resctrl/ctrlmondata.c index bf87eed826ff..547048f7bee7 100644 --- a/fs/resctrl/ctrlmondata.c +++ b/fs/resctrl/ctrlmondata.c @@ -65,7 +65,11 @@ static bool bw_validate(char *buf, unsigned long *data, struct rdt_resource *r) return false; } - *data = roundup(bw, (unsigned long)r->membw.bw_gran); + if (!IS_ENABLED(CONFIG_ARM64_MPAM)) + *data = roundup(bw, (unsigned long)r->membw.bw_gran); + else + *data = bw; + return true; } -- Gitee From 7d075bdfddcbf00cd4fc9d2673da7a527d545bbb Mon Sep 17 00:00:00 2001 From: Zeng Heng Date: Thu, 6 Nov 2025 15:46:10 +0800 Subject: [PATCH 2/2] arm64/mpam: Add quirk for L3 CPBM validity check hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ICX9YF -------------------------------- On specific chip models, the CPBM interface does not permit bits 18 and 17 to be set independently. Therefore, add the validity check for L3 CPBM. Fixes: f3a3763f845e ("arm64/mpam: Add quirk for hisi cpbm_wd field") Signed-off-by: Zeng Heng --- drivers/platform/mpam/mpam_resctrl.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/platform/mpam/mpam_resctrl.c b/drivers/platform/mpam/mpam_resctrl.c index 658ef77f676c..e3ff6a8354a9 100644 --- a/drivers/platform/mpam/mpam_resctrl.c +++ b/drivers/platform/mpam/mpam_resctrl.c @@ -1322,6 +1322,26 @@ u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_domain *d, } } +static bool mpam_cpbm_hisi_check_invalid(struct rdt_resource *r, + unsigned long val) +{ + static const struct midr_range cpus[] = { + MIDR_ALL_VERSIONS(MIDR_HISI_HIP12), + { /* sentinel */ } + }; + + if (!is_midr_in_range_list(cpus)) + return false; + + if (r->cache_level != 3) + return false; + + if (val & ~(BIT(18) | BIT(17))) + return false; + + return true; +} + int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_domain *d, u32 closid, enum resctrl_conf_type t, u32 cfg_val) { @@ -1349,6 +1369,9 @@ int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_domain *d, switch (r->rid) { case RDT_RESOURCE_L2: case RDT_RESOURCE_L3: + if (mpam_cpbm_hisi_check_invalid(r, cfg_val)) + return -EINVAL; + /* TODO: Scaling is not yet supported */ cfg.cpbm = cfg_val; mpam_set_feature(mpam_feat_cpor_part, &cfg); -- Gitee