提交 310712f9 编写于 作者: J James Morse 提交者: Zheng Zengkai

arm64: Use the clearbhb instruction in mitigations

stable inclusion
from stable-v5.10.105
commit 551717cf3b58f11311d10f70eb027d4b275135de
category: bugfix
bugzilla: 186460 https://gitee.com/src-openeuler/kernel/issues/I53MHA
CVE: CVE-2022-23960

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=551717cf3b58

--------------------------------

commit 228a26b9 upstream.

Future CPUs may implement a clearbhb instruction that is sufficient
to mitigate SpectreBHB. CPUs that implement this instruction, but
not CSV2.3 must be affected by Spectre-BHB.

Add support to use this instruction as the BHB mitigation on CPUs
that support it. The instruction is in the hint space, so it will
be treated by a NOP as older CPUs.
Reviewed-by: NRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Reviewed-by: NCatalin Marinas <catalin.marinas@arm.com>
[ modified for stable: Use a KVM vector template instead of alternatives,
  removed bitmap of mitigations ]
Signed-off-by: NJames Morse <james.morse@arm.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NChen Jiahao <chenjiahao16@huawei.com>
Reviewed-by: NLiao Chang <liaochang1@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 69c49d89
......@@ -106,6 +106,13 @@
hint #20
.endm
/*
* Clear Branch History instruction
*/
.macro clearbhb
hint #22
.endm
/*
* Speculation barrier
*/
......
......@@ -623,6 +623,19 @@ static inline bool supports_csv2p3(int scope)
return csv2_val == 3;
}
static inline bool supports_clearbhb(int scope)
{
u64 isar2;
if (scope == SCOPE_LOCAL_CPU)
isar2 = read_sysreg_s(SYS_ID_AA64ISAR2_EL1);
else
isar2 = read_sanitised_ftr_reg(SYS_ID_AA64ISAR2_EL1);
return cpuid_feature_extract_unsigned_field(isar2,
ID_AA64ISAR2_CLEARBHB_SHIFT);
}
static inline bool system_supports_32bit_el0(void)
{
return cpus_have_const_cap(ARM64_HAS_32BIT_EL0);
......
......@@ -64,6 +64,7 @@ enum aarch64_insn_hint_cr_op {
AARCH64_INSN_HINT_PSB = 0x11 << 5,
AARCH64_INSN_HINT_TSB = 0x12 << 5,
AARCH64_INSN_HINT_CSDB = 0x14 << 5,
AARCH64_INSN_HINT_CLEARBHB = 0x16 << 5,
AARCH64_INSN_HINT_BTI = 0x20 << 5,
AARCH64_INSN_HINT_BTIC = 0x22 << 5,
......
......@@ -37,6 +37,7 @@
#define __SMCCC_WORKAROUND_1_SMC_SZ 36
#define __SMCCC_WORKAROUND_3_SMC_SZ 36
#define __SPECTRE_BHB_LOOP_SZ 44
#define __SPECTRE_BHB_CLEARBHB_SZ 12
#define KVM_HOST_SMCCC_ID(id) \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
......@@ -205,6 +206,7 @@ extern char __smccc_workaround_3_smc[__SMCCC_WORKAROUND_3_SMC_SZ];
extern char __spectre_bhb_loop_k8[__SPECTRE_BHB_LOOP_SZ];
extern char __spectre_bhb_loop_k24[__SPECTRE_BHB_LOOP_SZ];
extern char __spectre_bhb_loop_k32[__SPECTRE_BHB_LOOP_SZ];
extern char __spectre_bhb_clearbhb[__SPECTRE_BHB_LOOP_SZ];
/*
* Obtain the PC-relative address of a kernel symbol
......
......@@ -707,6 +707,7 @@
#define ID_AA64ISAR1_GPI_IMP_DEF 0x1
/* id_aa64isar2 */
#define ID_AA64ISAR2_CLEARBHB_SHIFT 28
#define ID_AA64ISAR2_RPRES_SHIFT 4
#define ID_AA64ISAR2_WFXT_SHIFT 0
......
......@@ -32,6 +32,12 @@ enum arm64_bp_harden_el1_vectors {
* canonical vectors.
*/
EL1_VECTOR_BHB_FW,
/*
* Use the ClearBHB instruction, before branching to the canonical
* vectors.
*/
EL1_VECTOR_BHB_CLEAR_INSN,
#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
/*
......@@ -43,6 +49,7 @@ enum arm64_bp_harden_el1_vectors {
#ifndef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
#define EL1_VECTOR_BHB_LOOP -1
#define EL1_VECTOR_BHB_FW -1
#define EL1_VECTOR_BHB_CLEAR_INSN -1
#endif /* !CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
/* The vectors to use on return from EL0. e.g. to remap the kernel */
......
......@@ -207,6 +207,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
};
static const struct arm64_ftr_bits ftr_id_aa64isar2[] = {
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_HIGHER_SAFE, ID_AA64ISAR2_CLEARBHB_SHIFT, 4, 0),
ARM64_FTR_END,
};
......
......@@ -815,6 +815,7 @@ alternative_else_nop_endif
#define BHB_MITIGATION_NONE 0
#define BHB_MITIGATION_LOOP 1
#define BHB_MITIGATION_FW 2
#define BHB_MITIGATION_INSN 3
.macro tramp_ventry, vector_start, regsize, kpti, bhb
.align 7
......@@ -831,6 +832,11 @@ alternative_else_nop_endif
__mitigate_spectre_bhb_loop x30
.endif // \bhb == BHB_MITIGATION_LOOP
.if \bhb == BHB_MITIGATION_INSN
clearbhb
isb
.endif // \bhb == BHB_MITIGATION_INSN
.if \kpti == 1
/*
* Defend against branch aliasing attacks by pushing a dummy
......@@ -907,6 +913,7 @@ SYM_CODE_START_NOALIGN(tramp_vectors)
#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
generate_tramp_vector kpti=1, bhb=BHB_MITIGATION_LOOP
generate_tramp_vector kpti=1, bhb=BHB_MITIGATION_FW
generate_tramp_vector kpti=1, bhb=BHB_MITIGATION_INSN
#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
generate_tramp_vector kpti=1, bhb=BHB_MITIGATION_NONE
SYM_CODE_END(tramp_vectors)
......@@ -969,6 +976,7 @@ SYM_CODE_START(__bp_harden_el1_vectors)
#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
generate_el1_vector bhb=BHB_MITIGATION_LOOP
generate_el1_vector bhb=BHB_MITIGATION_FW
generate_el1_vector bhb=BHB_MITIGATION_INSN
#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
SYM_CODE_END(__bp_harden_el1_vectors)
.popsection
......
......@@ -824,6 +824,7 @@ int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which)
* - Mitigated by a branchy loop a CPU specific number of times, and listed
* in our "loop mitigated list".
* - Mitigated in software by the firmware Spectre v2 call.
* - Has the ClearBHB instruction to perform the mitigation.
* - Has the 'Exception Clears Branch History Buffer' (ECBHB) feature, so no
* software mitigation in the vectors is needed.
* - Has CSV2.3, so is unaffected.
......@@ -946,6 +947,9 @@ bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry,
if (supports_csv2p3(scope))
return false;
if (supports_clearbhb(scope))
return true;
if (spectre_bhb_loop_affected(scope))
return true;
......@@ -984,6 +988,8 @@ static int kvm_bhb_get_vecs_size(const char *start)
start == __spectre_bhb_loop_k24 ||
start == __spectre_bhb_loop_k32)
return __SPECTRE_BHB_LOOP_SZ;
else if (start == __spectre_bhb_clearbhb)
return __SPECTRE_BHB_CLEARBHB_SZ;
return 0;
}
......@@ -1024,6 +1030,7 @@ static void kvm_setup_bhb_slot(const char *hyp_vecs_start)
#define __spectre_bhb_loop_k8 NULL
#define __spectre_bhb_loop_k24 NULL
#define __spectre_bhb_loop_k32 NULL
#define __spectre_bhb_clearbhb NULL
static void kvm_setup_bhb_slot(const char *hyp_vecs_start) { }
#endif /* CONFIG_KVM */
......@@ -1042,6 +1049,11 @@ void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *entry)
} else if (cpu_mitigations_off()) {
pr_info_once("spectre-bhb mitigation disabled by command line option\n");
} else if (supports_ecbhb(SCOPE_LOCAL_CPU)) {
state = SPECTRE_MITIGATED;
} else if (supports_clearbhb(SCOPE_LOCAL_CPU)) {
kvm_setup_bhb_slot(__spectre_bhb_clearbhb);
this_cpu_set_vectors(EL1_VECTOR_BHB_CLEAR_INSN);
state = SPECTRE_MITIGATED;
} else if (spectre_bhb_loop_affected(SCOPE_LOCAL_CPU)) {
switch (spectre_bhb_loop_affected(SCOPE_SYSTEM)) {
......
......@@ -96,3 +96,12 @@ SYM_DATA_START(__spectre_bhb_loop_k32)
1: .org __spectre_bhb_loop_k32 + __SPECTRE_BHB_LOOP_SZ
.org 1b
SYM_DATA_END(__spectre_bhb_loop_k32)
.global __spectre_bhb_clearbhb
SYM_DATA_START(__spectre_bhb_clearbhb)
esb
clearbhb
isb
1: .org __spectre_bhb_clearbhb + __SPECTRE_BHB_CLEARBHB_SZ
.org 1b
SYM_DATA_END(__spectre_bhb_clearbhb)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册