hulk inclusion category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9OXPO
--------------------------------
If BIOS firmware doesn't enable MPAM function under EL3 environment, while the hardware has the MPAM ability, that would cause illegal instruction fault when access MPAM registers.
Fixes: 21771eaaf93a ("arm64: cpufeature: discover CPU support for MPAM") Signed-off-by: Zeng Heng zengheng4@huawei.com --- arch/arm64/include/asm/cpufeature.h | 9 +++++++ arch/arm64/kernel/cpufeature.c | 13 +++++++--- arch/arm64/kernel/cpuinfo.c | 1 + arch/arm64/kernel/mpam.c | 38 ++++++++++++++++++++++++++--- 4 files changed, 53 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index 2af4c7ad7dc5..f8ec4b20fa69 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h @@ -858,6 +858,15 @@ static inline bool cpus_support_mpam(void) cpus_have_final_cap(ARM64_MPAM); }
+#ifdef CONFIG_ARM64_MPAM +bool mpam_detect_is_enabled(void); +#else +static inline bool mpam_detect_is_enabled(void) +{ + return false; +} +#endif + int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt); bool try_emulate_mrs(struct pt_regs *regs, u32 isn);
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index f94bc6eb83e0..f4f3ad670391 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1078,8 +1078,9 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info) vec_init_vq_map(ARM64_VEC_SME); }
- if (id_aa64pfr0_mpam(info->reg_id_aa64pfr0) || - id_aa64pfr1_mpamfrac(info->reg_id_aa64pfr1)) + if (mpam_detect_is_enabled() && + (id_aa64pfr0_mpam(info->reg_id_aa64pfr0) || + id_aa64pfr1_mpamfrac(info->reg_id_aa64pfr1))) init_cpu_ftr_reg(SYS_MPAMIDR_EL1, info->reg_mpamidr);
if (id_aa64pfr1_mte(info->reg_id_aa64pfr1)) @@ -1341,8 +1342,9 @@ void update_cpu_features(int cpu, vec_update_vq_map(ARM64_VEC_SME); }
- if (id_aa64pfr0_mpam(info->reg_id_aa64pfr0) || - id_aa64pfr1_mpamfrac(info->reg_id_aa64pfr1)) { + if (mpam_detect_is_enabled() && + (id_aa64pfr0_mpam(info->reg_id_aa64pfr0) || + id_aa64pfr1_mpamfrac(info->reg_id_aa64pfr1))) { taint |= check_update_ftr_reg(SYS_MPAMIDR_EL1, cpu, info->reg_mpamidr, boot->reg_mpamidr); } @@ -2317,6 +2319,9 @@ test_has_mpam(const struct arm64_cpu_capabilities *entry, int scope) !id_aa64pfr1_mpamfrac(pfr1)) return false;
+ if (!mpam_detect_is_enabled()) + return false; + /* Check firmware actually enabled MPAM on this cpu. */ return (read_sysreg_s(SYS_MPAM1_EL1) & MPAM_SYSREG_EN); } diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c index 5ad8d8697d56..7466b6066d87 100644 --- a/arch/arm64/kernel/cpuinfo.c +++ b/arch/arm64/kernel/cpuinfo.c @@ -461,6 +461,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info) __cpuinfo_store_cpu_32bit(&info->aarch32);
if (IS_ENABLED(CONFIG_ARM64_MPAM) && + mpam_detect_is_enabled() && (id_aa64pfr0_mpam(info->reg_id_aa64pfr0) || id_aa64pfr1_mpamfrac(info->reg_id_aa64pfr1))) info->reg_mpamidr = read_cpuid(MPAMIDR_EL1); diff --git a/arch/arm64/kernel/mpam.c b/arch/arm64/kernel/mpam.c index 8fd9dbdc2b01..87411609407e 100644 --- a/arch/arm64/kernel/mpam.c +++ b/arch/arm64/kernel/mpam.c @@ -13,15 +13,45 @@ DEFINE_STATIC_KEY_FALSE(mpam_enabled); DEFINE_PER_CPU(u64, arm64_mpam_default); DEFINE_PER_CPU(u64, arm64_mpam_current);
+static const struct midr_range mpam_disable_list[] = { + MIDR_ALL_VERSIONS(MIDR_HISI_TSV110), + { /* sentinel */ } +}; + +static bool __read_mostly mpam_detect_enabled; +static int __init mpam_setup(char *str) +{ + if (!is_midr_in_range_list(read_cpuid_id(), mpam_disable_list)) + mpam_detect_enabled = true; + + if (!strcmp(str, "acpi")) + mpam_detect_enabled = true; + + return 0; +} +early_param("mpam", mpam_setup); + +bool mpam_detect_is_enabled(void) +{ + return mpam_detect_enabled; +} + static int __init arm64_mpam_register_cpus(void) { + u16 partid_max; + u64 mpamidr; + u8 pmg_max; + if (is_kdump_kernel()) return 0;
- u64 mpamidr = read_sanitised_ftr_reg(SYS_MPAMIDR_EL1); - u16 partid_max = FIELD_GET(MPAMIDR_PARTID_MAX, mpamidr); - u8 pmg_max = FIELD_GET(MPAMIDR_PMG_MAX, mpamidr); + if (!mpam_detect_is_enabled()) + return 0; + + mpamidr = read_sanitised_ftr_reg(SYS_MPAMIDR_EL1); + partid_max = FIELD_GET(MPAMIDR_PARTID_MAX, mpamidr); + pmg_max = FIELD_GET(MPAMIDR_PMG_MAX, mpamidr);
return mpam_register_requestor(partid_max, pmg_max); } -arch_initcall(arm64_mpam_register_cpus) +arch_initcall(arm64_mpam_register_cpus);
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/11657 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/U...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/11657 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/U...