diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index c4d4ab854e81a3e671a42086255031ac61dcfb6d..6f73a51d24229a61c101d8953f3208da34941892 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h @@ -652,6 +652,20 @@ static inline bool cpu_supports_mixed_endian_el0(void) return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1)); } +static inline bool supports_cnp(int scope) +{ + u64 mmfr2; + u8 cnp; + + if (scope == SCOPE_LOCAL_CPU) + mmfr2 = read_sysreg_s(SYS_ID_AA64MMFR2_EL1); + else + mmfr2 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR2_EL1); + + cnp = cpuid_feature_extract_unsigned_field(mmfr2, + ID_AA64MMFR2_EL1_CnP_SHIFT); + return cnp == 1; +} static inline bool supports_csv2p3(int scope) { diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index 91e654e61f7307dc4b95f95a2cfe1f92aa760750..25bf46c7ce51b81eb9bcfdad0c20a2cc5f60a1a4 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -60,6 +60,15 @@ is_kryo_midr(const struct arm64_cpu_capabilities *entry, int scope) return model == entry->midr_range.model; } +#ifdef CONFIG_HISILICON_ERRATUM_162100125 +static bool +hisilicon_162100125_match(const struct arm64_cpu_capabilities *entry, + int scope) +{ + return is_affected_midr_range_list(entry, scope) && supports_cnp(scope); +} +#endif + #ifdef CONFIG_HISILICON_ERRATUM_1980005 static bool hisilicon_1980005_match(const struct arm64_cpu_capabilities *entry, @@ -661,7 +670,9 @@ const struct arm64_cpu_capabilities arm64_errata[] = { { .desc = "Hisilicon erratum 162100125", .capability = ARM64_WORKAROUND_HISILICON_ERRATUM_162100125, - ERRATA_MIDR_RANGE_LIST(hisilicon_erratum_162100125_cpus), + .matches = hisilicon_162100125_match, + .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, + .midr_range_list = hisilicon_erratum_162100125_cpus, }, #endif #ifdef CONFIG_HISILICON_ERRATUM_1980005