Skip to content

Commit 641d804

Browse files
committed
Merge branch 'for-next/spectre-bhb' into for-next/core
Merge in the latest Spectre mess to fix up conflicts with what was already queued for 5.18 when the embargo finally lifted. * for-next/spectre-bhb: (21 commits) arm64: Do not include __READ_ONCE() block in assembly files arm64: proton-pack: Include unprivileged eBPF status in Spectre v2 mitigation reporting arm64: Use the clearbhb instruction in mitigations KVM: arm64: Allow SMCCC_ARCH_WORKAROUND_3 to be discovered and migrated arm64: Mitigate spectre style branch history side channels arm64: proton-pack: Report Spectre-BHB vulnerabilities as part of Spectre-v2 arm64: Add percpu vectors for EL1 arm64: entry: Add macro for reading symbol addresses from the trampoline arm64: entry: Add vectors that have the bhb mitigation sequences arm64: entry: Add non-kpti __bp_harden_el1_vectors for mitigations arm64: entry: Allow the trampoline text to occupy multiple pages arm64: entry: Make the kpti trampoline's kpti sequence optional arm64: entry: Move trampoline macros out of ifdef'd section arm64: entry: Don't assume tramp_vectors is the start of the vectors arm64: entry: Allow tramp_alias to access symbols after the 4K boundary arm64: entry: Move the trampoline data page before the text page arm64: entry: Free up another register on kpti's tramp_exit path arm64: entry: Make the trampoline cleanup optional KVM: arm64: Allow indirect vectors to be used without SPECTRE_V3A arm64: spectre: Rename spectre_v4_patch_fw_mitigation_conduit ...
2 parents 8d93b7a + 52c9f93 commit 641d804

28 files changed

Lines changed: 832 additions & 78 deletions

arch/arm64/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,6 +1387,15 @@ config UNMAP_KERNEL_AT_EL0
13871387

13881388
If unsure, say Y.
13891389

1390+
config MITIGATE_SPECTRE_BRANCH_HISTORY
1391+
bool "Mitigate Spectre style attacks against branch history" if EXPERT
1392+
default y
1393+
help
1394+
Speculation attacks against some high-performance processors can
1395+
make use of branch history to influence future speculation.
1396+
When taking an exception from user-space, a sequence of branches
1397+
or a firmware call overwrites the branch history.
1398+
13901399
config RODATA_FULL_DEFAULT_ENABLED
13911400
bool "Apply r/o permissions of VM areas also to their linear aliases"
13921401
default y

arch/arm64/include/asm/assembler.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,13 @@
108108
hint #20
109109
.endm
110110

111+
/*
112+
* Clear Branch History instruction
113+
*/
114+
.macro clearbhb
115+
hint #22
116+
.endm
117+
111118
/*
112119
* Speculation barrier
113120
*/
@@ -845,4 +852,50 @@ alternative_endif
845852

846853
#endif /* GNU_PROPERTY_AARCH64_FEATURE_1_DEFAULT */
847854

855+
.macro __mitigate_spectre_bhb_loop tmp
856+
#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
857+
alternative_cb spectre_bhb_patch_loop_iter
858+
mov \tmp, #32 // Patched to correct the immediate
859+
alternative_cb_end
860+
.Lspectre_bhb_loop\@:
861+
b . + 4
862+
subs \tmp, \tmp, #1
863+
b.ne .Lspectre_bhb_loop\@
864+
sb
865+
#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
866+
.endm
867+
868+
.macro mitigate_spectre_bhb_loop tmp
869+
#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
870+
alternative_cb spectre_bhb_patch_loop_mitigation_enable
871+
b .L_spectre_bhb_loop_done\@ // Patched to NOP
872+
alternative_cb_end
873+
__mitigate_spectre_bhb_loop \tmp
874+
.L_spectre_bhb_loop_done\@:
875+
#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
876+
.endm
877+
878+
/* Save/restores x0-x3 to the stack */
879+
.macro __mitigate_spectre_bhb_fw
880+
#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
881+
stp x0, x1, [sp, #-16]!
882+
stp x2, x3, [sp, #-16]!
883+
mov w0, #ARM_SMCCC_ARCH_WORKAROUND_3
884+
alternative_cb smccc_patch_fw_mitigation_conduit
885+
nop // Patched to SMC/HVC #0
886+
alternative_cb_end
887+
ldp x2, x3, [sp], #16
888+
ldp x0, x1, [sp], #16
889+
#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
890+
.endm
891+
892+
.macro mitigate_spectre_bhb_clear_insn
893+
#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
894+
alternative_cb spectre_bhb_patch_clearbhb
895+
/* Patched to NOP when not supported */
896+
clearbhb
897+
isb
898+
alternative_cb_end
899+
#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */
900+
.endm
848901
#endif /* __ASM_ASSEMBLER_H */

arch/arm64/include/asm/cpufeature.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,35 @@ static inline bool cpu_supports_mixed_endian_el0(void)
640640
return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1));
641641
}
642642

643+
644+
static inline bool supports_csv2p3(int scope)
645+
{
646+
u64 pfr0;
647+
u8 csv2_val;
648+
649+
if (scope == SCOPE_LOCAL_CPU)
650+
pfr0 = read_sysreg_s(SYS_ID_AA64PFR0_EL1);
651+
else
652+
pfr0 = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
653+
654+
csv2_val = cpuid_feature_extract_unsigned_field(pfr0,
655+
ID_AA64PFR0_CSV2_SHIFT);
656+
return csv2_val == 3;
657+
}
658+
659+
static inline bool supports_clearbhb(int scope)
660+
{
661+
u64 isar2;
662+
663+
if (scope == SCOPE_LOCAL_CPU)
664+
isar2 = read_sysreg_s(SYS_ID_AA64ISAR2_EL1);
665+
else
666+
isar2 = read_sanitised_ftr_reg(SYS_ID_AA64ISAR2_EL1);
667+
668+
return cpuid_feature_extract_unsigned_field(isar2,
669+
ID_AA64ISAR2_CLEARBHB_SHIFT);
670+
}
671+
643672
const struct cpumask *system_32bit_el0_cpumask(void);
644673
DECLARE_STATIC_KEY_FALSE(arm64_mismatched_32bit_el0);
645674

arch/arm64/include/asm/cputype.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,14 @@
7373
#define ARM_CPU_PART_CORTEX_A76 0xD0B
7474
#define ARM_CPU_PART_NEOVERSE_N1 0xD0C
7575
#define ARM_CPU_PART_CORTEX_A77 0xD0D
76+
#define ARM_CPU_PART_NEOVERSE_V1 0xD40
77+
#define ARM_CPU_PART_CORTEX_A78 0xD41
78+
#define ARM_CPU_PART_CORTEX_X1 0xD44
7679
#define ARM_CPU_PART_CORTEX_A510 0xD46
7780
#define ARM_CPU_PART_CORTEX_A710 0xD47
7881
#define ARM_CPU_PART_CORTEX_X2 0xD48
7982
#define ARM_CPU_PART_NEOVERSE_N2 0xD49
83+
#define ARM_CPU_PART_CORTEX_A78C 0xD4B
8084

8185
#define APM_CPU_PART_POTENZA 0x000
8286

@@ -124,10 +128,14 @@
124128
#define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76)
125129
#define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1)
126130
#define MIDR_CORTEX_A77 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77)
131+
#define MIDR_NEOVERSE_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V1)
132+
#define MIDR_CORTEX_A78 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78)
133+
#define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1)
127134
#define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510)
128135
#define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
129136
#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
130137
#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
138+
#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
131139
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
132140
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
133141
#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)

arch/arm64/include/asm/fixmap.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,11 @@ enum fixed_addresses {
6262
#endif /* CONFIG_ACPI_APEI_GHES */
6363

6464
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
65+
FIX_ENTRY_TRAMP_TEXT3,
66+
FIX_ENTRY_TRAMP_TEXT2,
67+
FIX_ENTRY_TRAMP_TEXT1,
6568
FIX_ENTRY_TRAMP_DATA,
66-
FIX_ENTRY_TRAMP_TEXT,
67-
#define TRAMP_VALIAS (__fix_to_virt(FIX_ENTRY_TRAMP_TEXT))
69+
#define TRAMP_VALIAS (__fix_to_virt(FIX_ENTRY_TRAMP_TEXT1))
6870
#endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */
6971
__end_of_permanent_fixed_addresses,
7072

arch/arm64/include/asm/insn.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ enum aarch64_insn_hint_cr_op {
6565
AARCH64_INSN_HINT_PSB = 0x11 << 5,
6666
AARCH64_INSN_HINT_TSB = 0x12 << 5,
6767
AARCH64_INSN_HINT_CSDB = 0x14 << 5,
68+
AARCH64_INSN_HINT_CLEARBHB = 0x16 << 5,
6869

6970
AARCH64_INSN_HINT_BTI = 0x20 << 5,
7071
AARCH64_INSN_HINT_BTIC = 0x22 << 5,

arch/arm64/include/asm/kvm_host.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,11 @@ static inline void kvm_init_host_cpu_context(struct kvm_cpu_context *cpu_ctxt)
714714
ctxt_sys_reg(cpu_ctxt, MPIDR_EL1) = read_cpuid_mpidr();
715715
}
716716

717+
static inline bool kvm_system_needs_idmapped_vectors(void)
718+
{
719+
return cpus_have_const_cap(ARM64_SPECTRE_V3A);
720+
}
721+
717722
void kvm_arm_vcpu_ptrauth_trap(struct kvm_vcpu *vcpu);
718723

719724
static inline void kvm_arch_hardware_unsetup(void) {}

arch/arm64/include/asm/rwonce.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#ifndef __ASM_RWONCE_H
66
#define __ASM_RWONCE_H
77

8-
#ifdef CONFIG_LTO
8+
#if defined(CONFIG_LTO) && !defined(__ASSEMBLY__)
99

1010
#include <linux/compiler_types.h>
1111
#include <asm/alternative-macros.h>
@@ -66,7 +66,7 @@
6666
})
6767

6868
#endif /* !BUILD_VDSO */
69-
#endif /* CONFIG_LTO */
69+
#endif /* CONFIG_LTO && !__ASSEMBLY__ */
7070

7171
#include <asm-generic/rwonce.h>
7272

arch/arm64/include/asm/sections.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,9 @@ extern char __mmuoff_data_start[], __mmuoff_data_end[];
2323
extern char __entry_tramp_text_start[], __entry_tramp_text_end[];
2424
extern char __relocate_new_kernel_start[], __relocate_new_kernel_end[];
2525

26+
static inline size_t entry_tramp_text_size(void)
27+
{
28+
return __entry_tramp_text_end - __entry_tramp_text_start;
29+
}
30+
2631
#endif /* __ASM_SECTIONS_H */

arch/arm64/include/asm/spectre.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,5 +94,9 @@ void spectre_v4_enable_task_mitigation(struct task_struct *tsk);
9494

9595
enum mitigation_state arm64_get_meltdown_state(void);
9696

97+
enum mitigation_state arm64_get_spectre_bhb_state(void);
98+
bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry, int scope);
99+
u8 spectre_bhb_loop_affected(int scope);
100+
void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *__unused);
97101
#endif /* __ASSEMBLY__ */
98102
#endif /* __ASM_SPECTRE_H */

0 commit comments

Comments
 (0)