From: Chen Jiahao chenjiahao16@huawei.com
hulk inclusion category: bugfix bugzilla: 186460, https://gitee.com/src-openeuler/kernel/issues/I53MHA CVE: CVE-2022-23960
--------------------------------
When introducing a new cpucaps macro ARM64_SPECTRE_BHB, ARM64_NCAPS was not able to modified easily due to KABI consistency. Here introduce a workaround to properly setup ARM64_SPECTRE_BHB beyond ARM64_NCAPS range.
Fixes: def2df575d30 ("KVM: arm64: Add templates for BHB mitigation sequences") Signed-off-by: Chen Jiahao chenjiahao16@huawei.com Reviewed-by: Zhang Jianhua chris.zjh@huawei.com Reviewed-by: Liao Chang liaochang1@huawei.com Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com --- arch/arm64/include/asm/cpufeature.h | 15 +++++++++++++++ arch/arm64/kernel/alternative.c | 5 +++++ arch/arm64/kernel/cpufeature.c | 3 +++ 3 files changed, 23 insertions(+)
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index bfb699957880..ffb0a1ec0088 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h @@ -368,6 +368,8 @@ extern struct static_key_false arm64_const_caps_ready; #define ARM64_NPATCHABLE (ARM64_NCAPS + 1) extern DECLARE_BITMAP(boot_capabilities, ARM64_NPATCHABLE);
+extern bool set_cap_spectre_bhb; + bool this_cpu_has_cap(unsigned int cap);
static inline bool cpu_have_feature(unsigned int num) @@ -378,15 +380,23 @@ static inline bool cpu_have_feature(unsigned int num) /* System capability check for constant caps */ static __always_inline bool __cpus_have_const_cap(int num) { + if (num == ARM64_SPECTRE_BHB) + return set_cap_spectre_bhb; + if (num >= ARM64_NCAPS) return false; + return static_branch_unlikely(&cpu_hwcap_keys[num]); }
static inline bool cpus_have_cap(unsigned int num) { + if (num == ARM64_SPECTRE_BHB) + return set_cap_spectre_bhb; + if (num >= ARM64_NCAPS) return false; + return test_bit(num, cpu_hwcaps); }
@@ -400,6 +410,11 @@ static __always_inline bool cpus_have_const_cap(int num)
static inline void cpus_set_cap(unsigned int num) { + if (num == ARM64_SPECTRE_BHB) { + set_cap_spectre_bhb = true; + return; + } + if (num >= ARM64_NCAPS) { pr_warn("Attempt to set an illegal CPU capability (%d >= %d)\n", num, ARM64_NCAPS); diff --git a/arch/arm64/kernel/alternative.c b/arch/arm64/kernel/alternative.c index 8511fc3b94bb..ce5a26080b46 100644 --- a/arch/arm64/kernel/alternative.c +++ b/arch/arm64/kernel/alternative.c @@ -41,8 +41,13 @@ struct alt_region { struct alt_instr *end; };
+bool set_cap_spectre_bhb; + bool alternative_is_applied(u16 cpufeature) { + if (cpufeature == ARM64_SPECTRE_BHB) + return set_cap_spectre_bhb; + if (WARN_ON(cpufeature >= ARM64_NCAPS)) return false;
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index aa9178e9acc6..996d3476f3c8 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1732,6 +1732,9 @@ __enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps, for (; caps->matches; caps++) { unsigned int num = caps->capability;
+ if (num == ARM64_SPECTRE_BHB) + set_cap_spectre_bhb = true; + if (!(caps->type & scope_mask) || !cpus_have_cap(num)) continue;