Skip to content

Commit cd22a8b

Browse files
committed
Merge tag 'arm64-spectre-bhb-for-v5.17-2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 spectre fixes from James Morse: "ARM64 Spectre-BHB mitigations: - Make EL1 vectors per-cpu - Add mitigation sequences to the EL1 and EL2 vectors on vulnerble CPUs - Implement ARCH_WORKAROUND_3 for KVM guests - Report Vulnerable when unprivileged eBPF is enabled" * tag 'arm64-spectre-bhb-for-v5.17-2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: 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 arm64: entry.S: Add ventry overflow sanity checks
2 parents fc55c23 + 58c9a50 commit cd22a8b

27 files changed

+830
-76
lines changed

arch/arm64/Kconfig

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

13841384
If unsure, say Y.
13851385

1386+
config MITIGATE_SPECTRE_BRANCH_HISTORY
1387+
bool "Mitigate Spectre style attacks against branch history" if EXPERT
1388+
default y
1389+
help
1390+
Speculation attacks against some high-performance processors can
1391+
make use of branch history to influence future speculation.
1392+
When taking an exception from user-space, a sequence of branches
1393+
or a firmware call overwrites the branch history.
1394+
13861395
config RODATA_FULL_DEFAULT_ENABLED
13871396
bool "Apply r/o permissions of VM areas also to their linear aliases"
13881397
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
*/
@@ -850,4 +857,50 @@ alternative_endif
850857

851858
#endif /* GNU_PROPERTY_AARCH64_FEATURE_1_DEFAULT */
852859

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

arch/arm64/include/asm/cpufeature.h

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

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

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

@@ -117,10 +121,14 @@
117121
#define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76)
118122
#define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1)
119123
#define MIDR_CORTEX_A77 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77)
124+
#define MIDR_NEOVERSE_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V1)
125+
#define MIDR_CORTEX_A78 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78)
126+
#define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1)
120127
#define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510)
121128
#define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
122129
#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
123130
#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
131+
#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
124132
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
125133
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
126134
#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/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
@@ -93,5 +93,9 @@ void spectre_v4_enable_task_mitigation(struct task_struct *tsk);
9393

9494
enum mitigation_state arm64_get_meltdown_state(void);
9595

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

arch/arm64/include/asm/sysreg.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,7 @@
773773
#define ID_AA64ISAR1_GPI_IMP_DEF 0x1
774774

775775
/* id_aa64isar2 */
776+
#define ID_AA64ISAR2_CLEARBHB_SHIFT 28
776777
#define ID_AA64ISAR2_RPRES_SHIFT 4
777778
#define ID_AA64ISAR2_WFXT_SHIFT 0
778779

@@ -904,6 +905,7 @@
904905
#endif
905906

906907
/* id_aa64mmfr1 */
908+
#define ID_AA64MMFR1_ECBHB_SHIFT 60
907909
#define ID_AA64MMFR1_AFP_SHIFT 44
908910
#define ID_AA64MMFR1_ETS_SHIFT 36
909911
#define ID_AA64MMFR1_TWED_SHIFT 32

0 commit comments

Comments
 (0)