Skip to content
This repository has been archived by the owner on Oct 2, 2024. It is now read-only.

Commit

Permalink
arm64: Use the clearbhb instruction in mitigations
Browse files Browse the repository at this point in the history
commit 228a26b912287934789023b4132ba76065d9491c 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: Russell King (Oracle) <[email protected]>
Reviewed-by: Catalin Marinas <[email protected]>
[ modified for stable: Use a KVM vector template instead of alternatives ]
Signed-off-by: James Morse <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
James Morse authored and reocat committed Jan 14, 2024
1 parent a8d0772 commit c727548
Show file tree
Hide file tree
Showing 8 changed files with 443 additions and 16 deletions.
25 changes: 25 additions & 0 deletions arch/arm64/include/asm/assembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,31 @@
dmb \opt
.endm

/*
* Value prediction barrier
*/
.macro csdb
hint #20
.endm

/*
* Clear Branch History instruction
*/
.macro clearbhb
hint #22
.endm

/*
* Sanitise a 64-bit bounded index wrt speculation, returning zero if out
* of bounds.
*/
.macro mask_nospec64, idx, limit, tmp
sub \tmp, \idx, \limit
bic \tmp, \tmp, \idx
and \idx, \idx, \tmp, asr #63
csdb
.endm

/*
* NOP sequence
*/
Expand Down
13 changes: 13 additions & 0 deletions arch/arm64/include/asm/cpufeature.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,19 @@ static inline bool cpu_supports_mixed_endian_el0(void)
return id_aa64mmfr0_mixed_endian_el0(read_cpuid(SYS_ID_AA64MMFR0_EL1));
}

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_system_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_cap(ARM64_HAS_32BIT_EL0);
Expand Down
3 changes: 3 additions & 0 deletions arch/arm64/include/asm/sysreg.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@
#define ID_AA64ISAR0_SHA1_SHIFT 8
#define ID_AA64ISAR0_AES_SHIFT 4

/* id_aa64isar2 */
#define ID_AA64ISAR2_CLEARBHB_SHIFT 28

/* id_aa64pfr0 */
#define ID_AA64PFR0_CSV2_SHIFT 56
#define ID_AA64PFR0_GIC_SHIFT 24
Expand Down
12 changes: 12 additions & 0 deletions arch/arm64/include/asm/vectors.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

/*
Expand All @@ -40,6 +46,12 @@ enum arm64_bp_harden_el1_vectors {
EL1_VECTOR_KPTI,
};

#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 */
DECLARE_PER_CPU_READ_MOSTLY(const char *, this_cpu_vector);

Expand Down
24 changes: 17 additions & 7 deletions arch/arm64/kernel/bpi.S
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,20 @@ ENTRY(__psci_hyp_bp_inval_start)
add sp, sp, #(8 * 18)
ENTRY(__psci_hyp_bp_inval_end)

ENTRY(__qcom_hyp_sanitize_link_stack_start)
stp x29, x30, [sp, #-16]!
.rept 16
bl . + 4
.endr
ldp x29, x30, [sp], #16
ENTRY(__qcom_hyp_sanitize_link_stack_end)
ENTRY(__spectre_bhb_loop_k32_start)
sub sp, sp, #(8 * 2)
stp x0, x1, [sp, #(8 * 0)]
mov x0, #32
2: b . + 4
subs x0, x0, #1
b.ne 2b
dsb nsh
isb
ldp x0, x1, [sp, #(8 * 0)]
add sp, sp, #(8 * 2)
ENTRY(__spectre_bhb_loop_k32_end)

ENTRY(__spectre_bhb_clearbhb_start)
hint #22 /* aka clearbhb */
isb
ENTRY(__spectre_bhb_clearbhb_end)
Loading

0 comments on commit c727548

Please sign in to comment.