Fix and rewrite arm64 spectre mitigations
Subsystems (3)
Will Deacon
maintainercover Fix and rewrite arm64 spectre mitigations
Hi everyone,
If there's something strange in your CPU, who you gonna call?
Well, if you're trundling along on an arm64 processor, git blame will suggest that Marc and I need to pick up the phone. Unfortunately, if the ghost in question is Spectre v2 or Spectre v4, then we'll have to call you back because our mitigations are in a pretty bad way. They used to work, but due to changes with the cpufeature code, they haven't been working properly for some time. And guess what? People haven't noticed because this stuff is practically impossible to test, even if you have a system where mitigations are available.
The temptation was to remove the code entirely, but after putting in some effort to untangle it, we ended up knocking it into a much better shape. Although that doesn't change the fact that we can't test it very well, it certainly appears to behave better than the old code in situations such as:
- Err... wanting mitigation on more than one CPU
- Not changing the mitigation state at runtime (i.e. after userspace has started running)
- Gracefully handling failure to bring late CPUs online (previously this would only happen _after_ updating the mitigation state!)
- Clear separation between mitigation state (am I vulnerable?) and policy (the user wants to go fast)
- Removal of the hideously expensive "dynamic" Spectre-v2 mitigation for KVM guests
- Being easier to read, including the addition of comments
As this is a complete rewrite, parts of the series are pretty grotty to review; it's easier to apply the whole lot first and then look at the new code, especially as the old implementation is pretty much unreadable anyway.
The first three patches are fixes targetting stable. Given the current state of this stuff, I think that the rest of the series is 5.10 material, as we're hardly going to make anything worse here.
Cheers,
Will
--->8
Marc Zyngier (8):
arm64: Make use of ARCH_WORKAROUND_1 even when KVM is not enabled
arm64: Run ARCH_WORKAROUND_1 enabling code on all CPUs
arm64: Run ARCH_WORKAROUND_2 enabling code on all CPUs
KVM: arm64: Set CSV2 for guests on hardware unaffected by Spectre-v2
KVM: arm64: Simplify handling of ARCH_WORKAROUND_2
KVM: arm64: Get rid of kvm_arm_have_ssbd()
KVM: arm64: Convert ARCH_WORKAROUND_2 to arm64_get_spectre_v4_state()
arm64: Get rid of arm64_ssbd_state
Will Deacon (11):
arm64: Remove Spectre-related CONFIG_* options
KVM: arm64: Replace CONFIG_KVM_INDIRECT_VECTORS with
CONFIG_RANDOMIZE_BASE
KVM: arm64: Simplify install_bp_hardening_cb()
arm64: Rename ARM64_HARDEN_BRANCH_PREDICTOR to ARM64_SPECTRE_V2
arm64: Introduce separate file for spectre mitigations and reporting
arm64: Rewrite Spectre-v2 mitigation code
arm64: Group start_thread() functions together
arm64: Treat SSBS as a non-strict system feature
arm64: Rename ARM64_SSBD to ARM64_SPECTRE_V4
arm64: Move SSBD prctl() handler alongside other spectre mitigation
code
arm64: Rewrite Spectre-v4 mitigation code
arch/arm64/Kconfig | 26 - arch/arm64/include/asm/cpucaps.h | 4 +- arch/arm64/include/asm/cpufeature.h | 24 - arch/arm64/include/asm/kvm_asm.h | 5 +- arch/arm64/include/asm/kvm_emulate.h | 14 - arch/arm64/include/asm/kvm_host.h | 40 -- arch/arm64/include/asm/kvm_mmu.h | 53 +- arch/arm64/include/asm/mmu.h | 11 +- arch/arm64/include/asm/processor.h | 44 +- arch/arm64/include/asm/spectre.h | 32 + arch/arm64/include/uapi/asm/kvm.h | 9 + arch/arm64/kernel/Makefile | 3 +- arch/arm64/kernel/cpu_errata.c | 487 +-------------- arch/arm64/kernel/cpufeature.c | 51 +- arch/arm64/kernel/entry.S | 10 +- arch/arm64/kernel/hibernate.c | 6 +- arch/arm64/kernel/image-vars.h | 2 - arch/arm64/kernel/process.c | 17 +- arch/arm64/kernel/proton-pack.c | 763 ++++++++++++++++++++++++ arch/arm64/kernel/ssbd.c | 129 ---- arch/arm64/kernel/suspend.c | 3 +- arch/arm64/kvm/Kconfig | 3 - arch/arm64/kvm/arm.c | 6 +- arch/arm64/kvm/hyp/Makefile | 2 +- arch/arm64/kvm/hyp/hyp-entry.S | 31 +- arch/arm64/kvm/hyp/include/hyp/switch.h | 33 - arch/arm64/kvm/hyp/nvhe/switch.c | 4 - arch/arm64/kvm/hyp/vhe/switch.c | 4 - arch/arm64/kvm/hypercalls.c | 33 +- arch/arm64/kvm/psci.c | 74 ++- arch/arm64/kvm/reset.c | 4 - arch/arm64/kvm/sys_regs.c | 3 + 32 files changed, 920 insertions(+), 1010 deletions(-) create mode 100644 arch/arm64/include/asm/spectre.h create mode 100644 arch/arm64/kernel/proton-pack.c delete mode 100644 arch/arm64/kernel/ssbd.c
Signature · 7 lines
2.28.0.681.g6f77f65b4e-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerPATCH 1/19 arm64: Make use of ARCH_WORKAROUND_1 even when KVM is not enabled
From: Marc Zyngier <[email protected]>
We seem to be pretending that we don't have any firmware mitigation when KVM is not compiled in, which is not quite expected.
Bring back the mitigation in this case.
--- arch/arm64/kernel/cpu_errata.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
arch/arm64/kernel/cpu_errata.c +5 -2
@@ -234,14 +234,17 @@ static int detect_harden_bp_fw(void) smccc_end =NULL ;break ; -#if IS_ENABLED (CONFIG_KVM )case SMCCC_CONDUIT_SMC : cb = call_smc_arch_workaround_1; +#if IS_ENABLED (CONFIG_KVM ) smccc_start = __smccc_workaround_1_smc; smccc_end = __smccc_workaround_1_smc + __SMCCC_WORKAROUND_1_SMC_SZ; -break ; +#else + smccc_start =NULL ; + smccc_end =NULL ;#endif +break ;default :return -1 ;
Signature · 1 line
2.28.0.681.g6f77f65b4e-goog
Will Deacon
maintainerPATCH 2/19 arm64: Run ARCH_WORKAROUND_1 enabling code on all CPUs
In reply to Will DeaconFrom: Marc Zyngier <[email protected]>
Commit 73f381660959 ("arm64: Advertise mitigation of Spectre-v2, or lack thereof") changed the way we deal with ARCH_WORKAROUND_1, by moving most of the enabling code to the .matches() callback.
This has the unfortunate effect that the workaround gets only enabled on the first affected CPU, and no other.
In order to address this, forcefully call the .matches() callback from a .cpu_enable() callback, which brings us back to the original behaviour.
--- arch/arm64/kernel/cpu_errata.c | 8 ++++++++ 1 file changed, 8 insertions(+)
arch/arm64/kernel/cpu_errata.c +8 -0
@@ -599,6 +599,12 @@ check_branch_predictor(const struct arm64_cpu_capabilities *entry, int scope)return (need_wa >0 ); } +static void +cpu_enable_branch_predictor_hardening (const struct arm64_cpu_capabilities *cap) +{ + cap->matches (cap,SCOPE_LOCAL_CPU ); +} +static const __maybe_unused struct midr_range tx2_family_cpus[] = {MIDR_ALL_VERSIONS (MIDR_BRCM_VULCAN ),MIDR_ALL_VERSIONS (MIDR_CAVIUM_THUNDERX2 ),
@@ -890,9 +896,11 @@ const struct arm64_cpu_capabilities arm64_errata[] = { },#endif { + .desc = "Branch predictor hardening", .capability = ARM64_HARDEN_BRANCH_PREDICTOR, .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, .matches = check_branch_predictor, + .cpu_enable = cpu_enable_branch_predictor_hardening, }, #ifdef CONFIG_RANDOMIZE_BASE {
Signature · 1 line
2.28.0.681.g6f77f65b4e-goog
Sasha Levin
maintainerRe: [PATCH 02/19] arm64: Run ARCH_WORKAROUND_1 enabling code on all CPUs
Hi
[This is an automated email]
This commit has been processed because it contains a "Fixes:" tag
fixing commit: 73f381660959 ("arm64: Advertise mitigation of Spectre-v2, or lack thereof").
The bot has tested the following trees: v5.8.10, v5.4.66, v4.19.146, v4.14.198.
v5.8.10: Build OK!
v5.4.66: Build OK!
v4.19.146: Build OK!
v4.14.198: Failed to apply! Possible dependencies:
4b472ffd1513 ("arm64: Enable ARM64_HARDEN_EL2_VECTORS on Cortex-A57 and A72")
631989303b06 ("Merge tag 'kvmarm-for-v4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD")
8892b71885df ("arm64: capabilities: Rework EL2 vector hardening entry")
93916beb7014 ("arm64: Enable workaround for Cavium TX2 erratum 219 when running SMT")
95b861a4a6d9 ("arm64: arch_timer: Add workaround for ARM erratum 1188873")
969f5ea62757 ("arm64: errata: Add workaround for Cortex-A76 erratum #1463225")
a457b0f7f50d ("arm64: Add configuration/documentation for Cortex-A76 erratum 1165522")
dc6ed61d2f82 ("arm64: Add temporary ERRATA_MIDR_ALL_VERSIONS compatibility macro")
e03a4e5bb743 ("arm64: Add silicon-errata.txt entry for ARM erratum 1188873")NOTE: The patch will not be queued to stable trees until it is upstream.
How should we proceed with this patch?
Signature · 2 lines
Thanks Sasha
Will Deacon
maintainerPATCH 3/19 arm64: Run ARCH_WORKAROUND_2 enabling code on all CPUs
In reply to Will DeaconFrom: Marc Zyngier <[email protected]>
Commit 606f8e7b27bf ("arm64: capabilities: Use linear array for detection and verification") changed the way we deal with per-CPU errata by only calling the .matches() callback until one CPU is found to be affected. At this point, .matches() stop being called, and .cpu_enable() will be called on all CPUs.
This breaks the ARCH_WORKAROUND_2 handling, as only a single CPU will be mitigated.
In order to address this, forcefully call the .matches() callback from a .cpu_enable() callback, which brings us back to the original behaviour.
--- arch/arm64/kernel/cpu_errata.c | 7 +++++++ 1 file changed, 7 insertions(+)
arch/arm64/kernel/cpu_errata.c +7 -0
@@ -457,6 +457,12 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,return required; } +static void cpu_enable_ssbd_mitigation (const struct arm64_cpu_capabilities *cap) +{ +if (ssbd_state !=ARM64_SSBD_FORCE_DISABLE ) + cap->matches (cap,SCOPE_LOCAL_CPU ); +} +/* known invulnerable cores */ static const struct midr_range arm64_ssb_cpus[] = {MIDR_ALL_VERSIONS (MIDR_CORTEX_A35 ),
@@ -914,6 +920,7 @@ const struct arm64_cpu_capabilities arm64_errata[] = { .capability = ARM64_SSBD, .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, .matches = has_ssbd_mitigation, + .cpu_enable = cpu_enable_ssbd_mitigation, .midr_range_list = arm64_ssb_cpus, },#ifdef CONFIG_ARM64_ERRATUM_1418040
Signature · 1 line
2.28.0.681.g6f77f65b4e-goog
Re: [PATCH 03/19] arm64: Run ARCH_WORKAROUND_2 enabling code on all CPUs
Quoted 11 lines · Will Deacon
From: Marc Zyngier <[email protected]>
Commit
606f8e7b27bf("arm64: capabilities: Use linear array for detection and verification") changed the way we deal with per-CPU errata by only calling the .matches() callback until one CPU is found to be affected. At this point, .matches() stop being called, and .cpu_enable() will be called on all CPUs.This breaks the
ARCH_WORKAROUND_2handling, as only a single CPU will be mitigated.
Quoted 7 lines
In order to address this, forcefully call the .matches() callback from a .cpu_enable() callback, which brings us back to the original behaviour.
Fixes 606f8e7b27bf ("arm64: capabilities: Use linear array for detection and verification")Cc <[email protected]>Signed-off-by Marc Zyngier <[email protected]>Signed-off-by Will Deacon <[email protected]>
Will Deacon
maintainerPATCH 4/19 arm64: Remove Spectre-related CONFIG_* options
In reply to Will DeaconThe spectre mitigations are too configurable for their own good, leading to confusing logic trying to figure out when we should mitigate and when we shouldn't. Although the plethora of command-line options need to stick around for backwards compatibility, the default-on CONFIG options that depend on EXPERT can be dropped, as the mitigations only do anything if the system is vulnerable, a mitigation is available and the command-line hasn't disabled it.
Remove CONFIG_HARDEN_BRANCH_PREDICTOR and CONFIG_ARM64_SSBD in favour of enabling this code unconditionally.
--- arch/arm64/Kconfig | 26 ------------------------- arch/arm64/include/asm/cpufeature.h | 4 ---- arch/arm64/include/asm/kvm_mmu.h | 7 ------- arch/arm64/include/asm/mmu.h | 9 --------- arch/arm64/kernel/Makefile | 3 +-- arch/arm64/kernel/cpu_errata.c | 19 ++---------------- arch/arm64/kernel/cpufeature.c | 4 ---- arch/arm64/kernel/entry.S | 4 ---- arch/arm64/kvm/Kconfig | 2 +- arch/arm64/kvm/hyp/hyp-entry.S | 2 -- arch/arm64/kvm/hyp/include/hyp/switch.h | 4 ---- 11 files changed, 4 insertions(+), 80 deletions(-)
arch/arm64/Kconfig +0 -26
@@ -1165,32 +1165,6 @@ config UNMAP_KERNEL_AT_EL0 If unsure, say Y. -config HARDEN_BRANCH_PREDICTOR - bool "Harden the branch predictor against aliasing attacks" if EXPERT - default y - help - Speculation attacks against some high-performance processors rely on - being able to manipulate the branch predictor for a victim context by - executing aliasing branches in the attacker context. Such attacks - can be partially mitigated against by clearing internal branch - predictor state and limiting the prediction logic in some situations. - - This config option will take CPU-specific actions to harden the - branch predictor against aliasing attacks and may rely on specific - instruction sequences or control bits being set by the system - firmware. - - If unsure, say Y. - -config ARM64_SSBD - bool "Speculative Store Bypass Disable" if EXPERT - default y - help - This enables mitigation of the bypassing of previous stores - by speculative loads. - - If unsure, say Y. - config RODATA_FULL_DEFAULT_ENABLED bool "Apply r/o permissions of VM areas also to their linear aliases" default y
arch/arm64/include/asm/cpufeature.h +0 -4
@@ -712,12 +712,8 @@ int get_spectre_v2_workaround_state(void);static inline int arm64_get_ssbd_state (void ) { -#ifdef CONFIG_ARM64_SSBD extern int ssbd_state;return ssbd_state; -#else -return ARM64_SSBD_UNKNOWN ; -#endif }void arm64_set_ssbd_mitigation (bool state);
arch/arm64/include/asm/kvm_mmu.h +0 -7
@@ -527,7 +527,6 @@ static inline int kvm_map_vectors(void) }#endif -#ifdef CONFIG_ARM64_SSBD DECLARE_PER_CPU_READ_MOSTLY (u64, arm64_ssbd_callback_required);static inline int hyp_map_aux_data (void )
@@ -544,12 +543,6 @@ static inline int hyp_map_aux_data(void) }return 0 ; } -#else -static inline int hyp_map_aux_data (void ) -{ -return 0 ; -} -#endif #define kvm_phys_to_vttbr (addr) phys_to_ttbr(addr)
arch/arm64/include/asm/mmu.h +0 -9
@@ -45,7 +45,6 @@ struct bp_hardening_data {bp_hardening_cb_t fn; }; -#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR DECLARE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data);static inline struct bp_hardening_data *arm64_get_bp_hardening_data (void )
@@ -64,14 +63,6 @@ static inline void arm64_apply_bp_hardening(void)if (d->fn) d->fn (); } -#else -static inline struct bp_hardening_data *arm64_get_bp_hardening_data (void ) -{ -return NULL ; -} - -static inline void arm64_apply_bp_hardening (void ) { } -#endif /* CONFIG_HARDEN_BRANCH_PREDICTOR */ extern void arm64_memblock_init (void );extern void paging_init (void );
arch/arm64/kernel/Makefile +1 -2
@@ -19,7 +19,7 @@ obj-y := debug-monitors.o entry.o irq.o fpsimd.o \ return_address.o cpuinfo.o cpu_errata.o \ cpufeature.o alternative.o cacheinfo.o \ smp.o smp_spin_table.o topology.o smccc-call.o \ - syscall.o + ssbd.o syscall.o targets += efi-entry.o
@@ -59,7 +59,6 @@ arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_CRASH_CORE) += crash_core.o obj-$(CONFIG_ARM_SDE_INTERFACE) += sdei.o -obj-$(CONFIG_ARM64_SSBD) += ssbd.o obj-$(CONFIG_ARM64_PTR_AUTH) += pointer_auth.o obj-$(CONFIG_SHADOW_CALL_STACK) += scs.o
arch/arm64/kernel/cpu_errata.c +2 -17
@@ -254,9 +254,7 @@ static int detect_harden_bp_fw(void) ((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR_V1)) cb = qcom_link_stack_sanitization; -if (IS_ENABLED (CONFIG_HARDEN_BRANCH_PREDICTOR )) -install_bp_hardening_cb (cb, smccc_start, smccc_end); - +install_bp_hardening_cb (cb, smccc_start, smccc_end);return 1 ; }
@@ -335,11 +333,6 @@ void arm64_set_ssbd_mitigation(bool state) {int conduit; -if (!IS_ENABLED (CONFIG_ARM64_SSBD )) { -pr_info_once ("SSBD disabled by kernel configuration\n" ); -return ; - } -if (this_cpu_has_cap (ARM64_SSBS )) {if (state) asm volatile(SET_PSTATE_SSBS(0));
@@ -584,12 +577,6 @@ check_branch_predictor(const struct arm64_cpu_capabilities *entry, int scope) __spectrev2_safe = false; -if (!IS_ENABLED (CONFIG_HARDEN_BRANCH_PREDICTOR )) { -pr_warn_once ("spectrev2 mitigation disabled by kernel configuration\n" ); - __hardenbp_enab = false; -return false; - } -/* forced off */ if (__nospectre_v2 ||cpu_mitigations_off ()) {pr_info_once ("spectrev2 mitigation disabled by command line option\n" );
@@ -1004,9 +991,7 @@ ssize_t cpu_show_spec_store_bypass(struct device *dev,switch (ssbd_state) {case ARM64_SSBD_KERNEL :case ARM64_SSBD_FORCE_ENABLE : -if (IS_ENABLED (CONFIG_ARM64_SSBD )) -return sprintf (buf, -"Mitigation: Speculative Store Bypass disabled via prctl\n" ); +return sprintf (buf,"Mitigation: Speculative Store Bypass disabled via prctl\n" ); }return sprintf (buf,"Vulnerable\n" );
arch/arm64/kernel/cpufeature.c +0 -4
@@ -1583,7 +1583,6 @@ static void cpu_has_fwb(const struct arm64_cpu_capabilities *__unused)WARN_ON (val & (7 <<27 |7 <<21 )); } -#ifdef CONFIG_ARM64_SSBD static int ssbs_emulation_handler (struct pt_regs *regs,u32 instr) {if (user_mode (regs))
@@ -1623,7 +1622,6 @@ static void cpu_enable_ssbs(const struct arm64_cpu_capabilities *__unused)arm64_set_ssbd_mitigation (true); } } -#endif /* CONFIG_ARM64_SSBD */ #ifdef CONFIG_ARM64_PAN static void cpu_enable_pan (const struct arm64_cpu_capabilities *__unused)
@@ -1976,7 +1974,6 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .field_pos = ID_AA64ISAR0_CRC32_SHIFT, .min_field_value = 1, }, -#ifdef CONFIG_ARM64_SSBD { .desc = "Speculative Store Bypassing Safe (SSBS)", .capability = ARM64_SSBS,
@@ -1988,7 +1985,6 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .min_field_value = ID_AA64PFR1_SSBS_PSTATE_ONLY, .cpu_enable = cpu_enable_ssbs, }, -#endif #ifdef CONFIG_ARM64_CNP { .desc = "Common not Private translations",
arch/arm64/kernel/entry.S +0 -4
@@ -132,7 +132,6 @@ alternative_else_nop_endif * them if required. */ .macro apply_ssbd, state, tmp1, tmp2 -#ifdef CONFIG_ARM64_SSBD alternative_cb arm64_enable_wa2_handling b .L__asm_ssbd_skip\@ alternative_cb_end
@@ -146,7 +145,6 @@ alternative_cb arm64_update_smccc_conduit nop // Patched to SMC/HVC #0 alternative_cb_end .L__asm_ssbd_skip\@: -#endif .endm .macro kernel_entry, el, regsize = 64
@@ -697,11 +695,9 @@ el0_irq_naked: bl trace_hardirqs_off #endif -#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR tbz x22, #55, 1f bl do_el0_irq_bp_hardening 1: -#endif irq_handler #ifdef CONFIG_TRACE_IRQFLAGS
arch/arm64/kvm/Kconfig +1 -1
@@ -58,7 +58,7 @@ config KVM_ARM_PMU virtual machines. config KVM_INDIRECT_VECTORS - def_bool HARDEN_BRANCH_PREDICTOR || RANDOMIZE_BASE + def_bool RANDOMIZE_BASE endif # KVM
arch/arm64/kvm/hyp/hyp-entry.S +0 -2
@@ -116,7 +116,6 @@ el1_hvc_guest: ARM_SMCCC_ARCH_WORKAROUND_2) cbnz w1, el1_trap -#ifdef CONFIG_ARM64_SSBD alternative_cb arm64_enable_wa2_handling b wa2_end alternative_cb_end
@@ -143,7 +142,6 @@ alternative_cb_end wa2_end: mov x2, xzr mov x1, xzr -#endif wa_epilogue: mov x0, xzr
arch/arm64/kvm/hyp/include/hyp/switch.h +0 -4
@@ -489,7 +489,6 @@ static inline bool __needs_ssbd_off(struct kvm_vcpu *vcpu)static inline void __set_guest_arch_workaround_state (struct kvm_vcpu *vcpu) { -#ifdef CONFIG_ARM64_SSBD /* * The host runs with the workaround always present. If the * guest wants it disabled, so be it...
@@ -497,19 +496,16 @@ static inline void __set_guest_arch_workaround_state(struct kvm_vcpu *vcpu)if (__needs_ssbd_off (vcpu) &&__hyp_this_cpu_read (arm64_ssbd_callback_required))arm_smccc_1_1_smc (ARM_SMCCC_ARCH_WORKAROUND_2 ,0 ,NULL ); -#endif }static inline void __set_host_arch_workaround_state (struct kvm_vcpu *vcpu) { -#ifdef CONFIG_ARM64_SSBD /* * If the guest has disabled the workaround, bring it back on. */ if (__needs_ssbd_off (vcpu) &&__hyp_this_cpu_read (arm64_ssbd_callback_required))arm_smccc_1_1_smc (ARM_SMCCC_ARCH_WORKAROUND_2 ,1 ,NULL ); -#endif }static inline void __kvm_unexpected_el2_exception (void )
Signature · 7 lines
2.28.0.681.g6f77f65b4e-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerPATCH 5/19 KVM: arm64: Replace CONFIG_KVM_INDIRECT_VECTORS with CONFIG_RANDOMIZE_BASE
In reply to Will DeaconThe removal of CONFIG_HARDEN_BRANCH_PREDICTOR means that CONFIG_KVM_INDIRECT_VECTORS is synonymous with CONFIG_RANDOMIZE_BASE, so replace it.
--- arch/arm64/include/asm/kvm_asm.h | 2 +- arch/arm64/include/asm/kvm_mmu.h | 2 +- arch/arm64/kernel/cpu_errata.c | 4 ++-- arch/arm64/kvm/Kconfig | 3 --- arch/arm64/kvm/hyp/Makefile | 2 +- arch/arm64/kvm/hyp/hyp-entry.S | 2 +- 6 files changed, 6 insertions(+), 9 deletions(-)
arch/arm64/include/asm/kvm_asm.h +1 -1
@@ -102,7 +102,7 @@ DECLARE_KVM_HYP_SYM(__kvm_hyp_vector);#define __kvm_hyp_init CHOOSE_NVHE_SYM(__kvm_hyp_init)#define __kvm_hyp_vector CHOOSE_HYP_SYM(__kvm_hyp_vector) -#ifdef CONFIG_KVM_INDIRECT_VECTORS +#ifdef CONFIG_RANDOMIZE_BASE extern atomic_t arm64_el2_vector_last_slot;DECLARE_KVM_HYP_SYM (__bp_harden_hyp_vecs);#define __bp_harden_hyp_vecs CHOOSE_HYP_SYM(__bp_harden_hyp_vecs)
arch/arm64/include/asm/kvm_mmu.h +1 -1
@@ -430,7 +430,7 @@ static inline int kvm_write_guest_lock(struct kvm *kvm, gpa_t gpa,return ret; } -#ifdef CONFIG_KVM_INDIRECT_VECTORS +#ifdef CONFIG_RANDOMIZE_BASE /* * EL2 vectors can be mapped and rerouted in a number of ways, * depending on the kernel configuration and CPU present:
arch/arm64/kernel/cpu_errata.c +2 -2
@@ -113,7 +113,7 @@ atomic_t arm64_el2_vector_last_slot = ATOMIC_INIT(-1); DEFINE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data); -#ifdef CONFIG_KVM_INDIRECT_VECTORS +#ifdef CONFIG_RANDOMIZE_BASE static void __copy_hyp_vect_bpi (int slot,const char *hyp_vecs_start,const char *hyp_vecs_end) {
@@ -167,7 +167,7 @@ static void install_bp_hardening_cb(bp_hardening_cb_t fn, {__this_cpu_write (bp_hardening_data.fn, fn); } -#endif /* CONFIG_KVM_INDIRECT_VECTORS */ +#endif /* CONFIG_RANDOMIZE_BASE */ #include <linux/arm-smccc.h>
arch/arm64/kvm/Kconfig +0 -3
@@ -57,9 +57,6 @@ config KVM_ARM_PMU Adds support for a virtual Performance Monitoring Unit (PMU) in virtual machines. -config KVM_INDIRECT_VECTORS - def_bool RANDOMIZE_BASE - endif # KVM endif # VIRTUALIZATION
arch/arm64/kvm/hyp/Makefile +1 -1
@@ -11,4 +11,4 @@ subdir-ccflags-y := -I$(incdir) \ $(DISABLE_STACKLEAK_PLUGIN) obj-$(CONFIG_KVM) += vhe/ nvhe/ -obj-$(CONFIG_KVM_INDIRECT_VECTORS) += smccc_wa.o +obj-$(CONFIG_RANDOMIZE_BASE) += smccc_wa.o
arch/arm64/kvm/hyp/hyp-entry.S +1 -1
@@ -286,7 +286,7 @@ SYM_CODE_START(__kvm_hyp_vector) valid_vect el1_error // Error 32-bit EL1 SYM_CODE_END(__kvm_hyp_vector) -#ifdef CONFIG_KVM_INDIRECT_VECTORS +#ifdef CONFIG_RANDOMIZE_BASE .macro hyp_ventry .align 7 1: esb
Signature · 7 lines
2.28.0.681.g6f77f65b4e-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerPATCH 6/19 KVM: arm64: Simplify install_bp_hardening_cb()
In reply to Will DeaconUse is_hyp_mode_available() to detect whether or not we need to patch the KVM vectors for branch hardening, which avoids the need to take the vector pointers as parameters.
--- arch/arm64/kernel/cpu_errata.c | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-)
arch/arm64/kernel/cpu_errata.c +7 -20
@@ -126,18 +126,19 @@ static void __copy_hyp_vect_bpi(int slot, const char *hyp_vecs_start,__flush_icache_range ((uintptr_t )dst, (uintptr_t )dst +SZ_2K ); } -static void install_bp_hardening_cb (bp_hardening_cb_t fn, -const char *hyp_vecs_start, -const char *hyp_vecs_end) +static void install_bp_hardening_cb (bp_hardening_cb_t fn) {static DEFINE_RAW_SPINLOCK (bp_lock);int cpu, slot =-1 ; +const char *hyp_vecs_start = __smccc_workaround_1_smc; +const char *hyp_vecs_end = __smccc_workaround_1_smc + + __SMCCC_WORKAROUND_1_SMC_SZ;/* * detect_harden_bp_fw() passes NULL for the hyp_vecs start/end if * we're a guest. Skip the hyp-vectors work. */ -if (!hyp_vecs_start) { +if (!is_hyp_mode_available ()) {__this_cpu_write (bp_hardening_data.fn, fn);return ; }
@@ -161,9 +162,7 @@ static void install_bp_hardening_cb(bp_hardening_cb_t fn, raw_spin_unlock(&bp_lock); }#else -static void install_bp_hardening_cb (bp_hardening_cb_t fn, -const char *hyp_vecs_start, -const char *hyp_vecs_end) +static void install_bp_hardening_cb (bp_hardening_cb_t fn) {__this_cpu_write (bp_hardening_data.fn, fn); }
@@ -209,7 +208,6 @@ early_param("nospectre_v2", parse_nospectre_v2);static int detect_harden_bp_fw (void ) {bp_hardening_cb_t cb; -void *smccc_start, *smccc_end;struct arm_smccc_res res;u32 midr =read_cpuid_id ();
@@ -229,21 +227,10 @@ static int detect_harden_bp_fw(void)switch (arm_smccc_1_1_get_conduit ()) {case SMCCC_CONDUIT_HVC : cb = call_hvc_arch_workaround_1; -/* This is a guest, no need to patch KVM vectors */ - smccc_start =NULL ; - smccc_end =NULL ;break ;case SMCCC_CONDUIT_SMC : cb = call_smc_arch_workaround_1; -#if IS_ENABLED (CONFIG_KVM ) - smccc_start = __smccc_workaround_1_smc; - smccc_end = __smccc_workaround_1_smc + - __SMCCC_WORKAROUND_1_SMC_SZ; -#else - smccc_start =NULL ; - smccc_end =NULL ; -#endif break ;default :
@@ -254,7 +241,7 @@ static int detect_harden_bp_fw(void) ((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR_V1)) cb = qcom_link_stack_sanitization; -install_bp_hardening_cb (cb, smccc_start, smccc_end); +install_bp_hardening_cb (cb);return 1 ; }
Signature · 7 lines
2.28.0.681.g6f77f65b4e-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerPATCH 7/19 arm64: Rename ARM64_HARDEN_BRANCH_PREDICTOR to ARM64_SPECTRE_V2
In reply to Will DeaconFor better or worse, the world knows about "Spectre" and not about "Branch predictor hardening". Rename ARM64_HARDEN_BRANCH_PREDICTOR to ARM64_SPECTRE_V2 as part of moving all of the Spectre mitigations into their own little corner.
--- arch/arm64/include/asm/cpucaps.h | 2 +- arch/arm64/include/asm/kvm_mmu.h | 27 +++++++++++++-------------- arch/arm64/include/asm/mmu.h | 2 +- arch/arm64/kernel/cpu_errata.c | 2 +- 4 files changed, 16 insertions(+), 17 deletions(-)
arch/arm64/include/asm/cpucaps.h +1 -1
@@ -31,7 +31,7 @@#define ARM64_HAS_DCPOP 21#define ARM64_SVE 22#define ARM64_UNMAP_KERNEL_AT_EL0 23 -#define ARM64_HARDEN_BRANCH_PREDICTOR 24 +#define ARM64_SPECTRE_V2 24#define ARM64_HAS_RAS_EXTN 25#define ARM64_WORKAROUND_843419 26#define ARM64_HAS_CACHE_IDC 27
arch/arm64/include/asm/kvm_mmu.h +13 -14
@@ -435,14 +435,13 @@ static inline int kvm_write_guest_lock(struct kvm *kvm, gpa_t gpa,* EL2 vectors can be mapped and rerouted in a number of ways, * depending on the kernel configuration and CPU present: * -* - If the CPU has the ARM64_HARDEN_BRANCH_PREDICTOR cap, the -* hardening sequence is placed in one of the vector slots, which is -* executed before jumping to the real vectors. +* - If the CPU is affected by Spectre-v2, the hardening sequence is +* placed in one of the vector slots, which is executed before jumping +* to the real vectors. * -* - If the CPU has both the ARM64_HARDEN_EL2_VECTORS cap and the -* ARM64_HARDEN_BRANCH_PREDICTOR cap, the slot containing the -* hardening sequence is mapped next to the idmap page, and executed -* before jumping to the real vectors. +* - If the CPU also has the ARM64_HARDEN_EL2_VECTORS cap, the slot +* containing the hardening sequence is mapped next to the idmap page, +* and executed before jumping to the real vectors. * * - If the CPU only has the ARM64_HARDEN_EL2_VECTORS cap, then an * empty slot is selected, mapped next to the idmap page, and
@@ -464,7 +463,7 @@ static inline void *kvm_get_hyp_vector(void)void *vect =kern_hyp_va (kvm_ksym_ref (__kvm_hyp_vector));int slot =-1 ; -if (cpus_have_const_cap (ARM64_HARDEN_BRANCH_PREDICTOR ) && data->fn) { +if (cpus_have_const_cap (ARM64_SPECTRE_V2 ) && data->fn) { vect =kern_hyp_va (kvm_ksym_ref (__bp_harden_hyp_vecs)); slot = data->hyp_vectors_slot; }
@@ -485,15 +484,15 @@ static inline void *kvm_get_hyp_vector(void)static inline int kvm_map_vectors (void ) {/* -* HBP = ARM64_HARDEN_BRANCH_PREDICTOR +* SV2 = ARM64_SPECTRE_V2 * HEL2 = ARM64_HARDEN_EL2_VECTORS * -* !HBP + !HEL2 -> use direct vectors -* HBP + !HEL2 -> use hardened vectors in place -* !HBP + HEL2 -> allocate one vector slot and use exec mapping -* HBP + HEL2 -> use hardened vertors and use exec mapping +* !SV2 + !HEL2 -> use direct vectors +* SV2 + !HEL2 -> use hardened vectors in place +* !SV2 + HEL2 -> allocate one vector slot and use exec mapping +* SV2 + HEL2 -> use hardened vertors and use exec mapping */ -if (cpus_have_const_cap (ARM64_HARDEN_BRANCH_PREDICTOR )) { +if (cpus_have_const_cap (ARM64_SPECTRE_V2 )) { __kvm_bp_vect_base =kvm_ksym_ref (__bp_harden_hyp_vecs); __kvm_bp_vect_base =kern_hyp_va (__kvm_bp_vect_base); }
arch/arm64/include/asm/mmu.h +1 -1
@@ -56,7 +56,7 @@ static inline void arm64_apply_bp_hardening(void) {struct bp_hardening_data *d; -if (!cpus_have_const_cap (ARM64_HARDEN_BRANCH_PREDICTOR )) +if (!cpus_have_const_cap (ARM64_SPECTRE_V2 ))return ; d =arm64_get_bp_hardening_data ();
arch/arm64/kernel/cpu_errata.c +1 -1
@@ -877,7 +877,7 @@ const struct arm64_cpu_capabilities arm64_errata[] = {#endif { .desc = "Branch predictor hardening", - .capability = ARM64_HARDEN_BRANCH_PREDICTOR, + .capability = ARM64_SPECTRE_V2, .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, .matches = check_branch_predictor, .cpu_enable = cpu_enable_branch_predictor_hardening,
Signature · 7 lines
2.28.0.681.g6f77f65b4e-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerPATCH 8/19 arm64: Introduce separate file for spectre mitigations and reporting
In reply to Will DeaconThe spectre mitigation code is spread over a few different files, which makes it both hard to follow, but also hard to remove it should we want to do that in future.
Introduce a new file for housing the spectre mitigations, and populate it with the spectre-v1 reporting code to start with.
--- arch/arm64/kernel/Makefile | 2 +- arch/arm64/kernel/cpu_errata.c | 6 ------ arch/arm64/kernel/proton-pack.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 arch/arm64/kernel/proton-pack.c
arch/arm64/kernel/Makefile +1 -1
@@ -19,7 +19,7 @@ obj-y := debug-monitors.o entry.o irq.o fpsimd.o \ return_address.o cpuinfo.o cpu_errata.o \ cpufeature.o alternative.o cacheinfo.o \ smp.o smp_spin_table.o topology.o smccc-call.o \ - ssbd.o syscall.o + ssbd.o syscall.o proton-pack.o targets += efi-entry.o
arch/arm64/kernel/cpu_errata.c +0 -6
@@ -949,12 +949,6 @@ const struct arm64_cpu_capabilities arm64_errata[] = { } }; -ssize_t cpu_show_spectre_v1 (struct device *dev,struct device_attribute *attr, -char *buf) -{ -return sprintf (buf,"Mitigation: __user pointer sanitization\n" ); -} -ssize_t cpu_show_spectre_v2 (struct device *dev,struct device_attribute *attr,char *buf) {
arch/arm64/kernel/proton-pack.c new file +32 -0
@@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* +* Handle detection, reporting and mitigation of Spectre v1, v2 and v4, as +* detailed at: +* +* https://developer.arm.com/support/arm-security-updates/speculative-processor-vulnerability +* +* This code was originally written hastily under an awful lot of stress and so +* aspects of it are somewhat hacky. Unfortunately, changing anything in here +* instantly makes me feel ill. Thanks, Jann. Thann. +* +* Copyright (C) 2018 ARM Ltd, All Rights Reserved. +* Copyright (C) 2020 Google LLC +* +* "If there's something strange in your neighbourhood, who you gonna call?" +* +* Authors: Will Deacon <[email protected]> and Marc Zyngier <[email protected]> +*/ + +#include <linux/device.h> + +/* +* Spectre v1. +* +* The kernel can't protect userspace for this one: it's each person for +* themselves. Advertise what we're doing and be done with it. +*/ +ssize_t cpu_show_spectre_v1 (struct device *dev,struct device_attribute *attr, +char *buf) +{ +return sprintf (buf,"Mitigation: __user pointer sanitization\n" ); +}
Signature · 7 lines
2.28.0.681.g6f77f65b4e-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerPATCH 9/19 arm64: Rewrite Spectre-v2 mitigation code
In reply to Will DeaconThe Spectre-v2 mitigation code is pretty unwieldy and hard to maintain. This is largely due to it being written hastily, without much clue as to how things would pan out, and also because it ends up mixing policy and state in such a way that it is very difficult to figure out what's going on.
Rewrite the Spectre-v2 mitigation so that it clearly separates state from policy and follows a more structured approach to handling the mitigation.
--- arch/arm64/include/asm/cpufeature.h | 6 - arch/arm64/include/asm/kvm_host.h | 17 -- arch/arm64/include/asm/processor.h | 1 + arch/arm64/include/asm/spectre.h | 27 +++ arch/arm64/kernel/cpu_errata.c | 236 +---------------------- arch/arm64/kernel/proton-pack.c | 288 ++++++++++++++++++++++++++++ arch/arm64/kvm/hypercalls.c | 8 +- arch/arm64/kvm/psci.c | 8 +- 8 files changed, 327 insertions(+), 264 deletions(-) create mode 100644 arch/arm64/include/asm/spectre.h
arch/arm64/include/asm/cpufeature.h +0 -6
@@ -698,12 +698,6 @@ static inline bool system_supports_tlb_range(void)cpus_have_const_cap (ARM64_HAS_TLB_RANGE ); } -#define ARM64_BP_HARDEN_UNKNOWN -1 -#define ARM64_BP_HARDEN_WA_NEEDED 0 -#define ARM64_BP_HARDEN_NOT_REQUIRED 1 - -int get_spectre_v2_workaround_state (void ); -#define ARM64_SSBD_UNKNOWN -1#define ARM64_SSBD_FORCE_DISABLE 0#define ARM64_SSBD_KERNEL 1
arch/arm64/include/asm/kvm_host.h +0 -17
@@ -631,23 +631,6 @@ static inline void kvm_set_pmu_events(u32 set, struct perf_event_attr *attr) {}static inline void kvm_clr_pmu_events (u32 clr) {}#endif -#define KVM_BP_HARDEN_UNKNOWN -1 -#define KVM_BP_HARDEN_WA_NEEDED 0 -#define KVM_BP_HARDEN_NOT_REQUIRED 1 - -static inline int kvm_arm_harden_branch_predictor (void ) -{ -switch (get_spectre_v2_workaround_state ()) { -case ARM64_BP_HARDEN_WA_NEEDED : -return KVM_BP_HARDEN_WA_NEEDED ; -case ARM64_BP_HARDEN_NOT_REQUIRED : -return KVM_BP_HARDEN_NOT_REQUIRED ; -case ARM64_BP_HARDEN_UNKNOWN : -default : -return KVM_BP_HARDEN_UNKNOWN ; - } -} -#define KVM_SSBD_UNKNOWN -1#define KVM_SSBD_FORCE_DISABLE 0#define KVM_SSBD_KERNEL 1
arch/arm64/include/asm/processor.h +1 -0
@@ -38,6 +38,7 @@#include <asm/pgtable-hwdef.h> #include <asm/pointer_auth.h> #include <asm/ptrace.h> +#include <asm/spectre.h> #include <asm/types.h> /*
arch/arm64/include/asm/spectre.h new file +27 -0
@@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +* Interface for managing mitigations for Spectre vulnerabilities. +* +* Copyright (C) 2020 Google LLC +* Author: Will Deacon <[email protected]> +*/ + +#ifndef __ASM_SPECTRE_H +#define __ASM_SPECTRE_H + +#include <asm/cpufeature.h> + +/* Watch out, ordering is important here. */ +enum mitigation_state { +SPECTRE_UNAFFECTED , +SPECTRE_MITIGATED , +SPECTRE_VULNERABLE , +}; + +struct task_struct ; + +enum mitigation_state arm64_get_spectre_v2_state (void ); +bool has_spectre_v2 (const struct arm64_cpu_capabilities *cap,int scope); +void spectre_v2_enable_mitigation (const struct arm64_cpu_capabilities *__unused); + +#endif /* __ASM_SPECTRE_H */
arch/arm64/kernel/cpu_errata.c +3 -233
262 lines not on this page · raw message
arch/arm64/kernel/proton-pack.c +288 -0
298 lines not on this page · raw message
arch/arm64/kvm/hypercalls.c +4 -4
@@ -24,13 +24,13 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) feature =smccc_get_arg1 (vcpu);switch (feature) {case ARM_SMCCC_ARCH_WORKAROUND_1 : -switch (kvm_arm_harden_branch_predictor ()) { -case KVM_BP_HARDEN_UNKNOWN : +switch (arm64_get_spectre_v2_state ()) { +case SPECTRE_VULNERABLE :break ; -case KVM_BP_HARDEN_WA_NEEDED : +case SPECTRE_MITIGATED : val =SMCCC_RET_SUCCESS ;break ; -case KVM_BP_HARDEN_NOT_REQUIRED : +case SPECTRE_UNAFFECTED : val =SMCCC_RET_NOT_REQUIRED ;break ; }
arch/arm64/kvm/psci.c +4 -4
@@ -425,12 +425,12 @@ static int get_kernel_wa_level(u64 regid) {switch (regid) {case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1 : -switch (kvm_arm_harden_branch_predictor ()) { -case KVM_BP_HARDEN_UNKNOWN : +switch (arm64_get_spectre_v2_state ()) { +case SPECTRE_VULNERABLE :return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL ; -case KVM_BP_HARDEN_WA_NEEDED : +case SPECTRE_MITIGATED :return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_AVAIL ; -case KVM_BP_HARDEN_NOT_REQUIRED : +case SPECTRE_UNAFFECTED :return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_REQUIRED ; }return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL ;
Signature · 7 lines
2.28.0.681.g6f77f65b4e-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerPATCH 10/19 KVM: arm64: Set CSV2 for guests on hardware unaffected by Spectre-v2
In reply to Will DeaconFrom: Marc Zyngier <[email protected]>
If the system is not affected by Spectre-v2, then advertise to the KVM guest that it is not affected, without the need for a safelist in the guest.
--- arch/arm64/kvm/sys_regs.c | 3 +++ 1 file changed, 3 insertions(+)
arch/arm64/kvm/sys_regs.c +3 -0
@@ -1131,6 +1131,9 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,if (!vcpu_has_sve (vcpu)) val &= ~(0xfUL <<ID_AA64PFR0_SVE_SHIFT ); val &= ~(0xfUL <<ID_AA64PFR0_AMU_SHIFT ); +if (!(val & (0xfUL <<ID_AA64PFR0_CSV2_SHIFT )) && +arm64_get_spectre_v2_state () ==SPECTRE_UNAFFECTED ) + val |= (1UL <<ID_AA64PFR0_CSV2_SHIFT ); }else if (id ==SYS_ID_AA64ISAR1_EL1 && !vcpu_has_ptrauth (vcpu)) { val &= ~((0xfUL << ID_AA64ISAR1_APA_SHIFT) | (0xfUL << ID_AA64ISAR1_API_SHIFT) |
Signature · 7 lines
2.28.0.681.g6f77f65b4e-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerPATCH 11/19 arm64: Group start_thread() functions together
In reply to Will DeaconThe is_ttbrX_addr() functions have somehow ended up in the middle of the start_thread() functions, so move them out of the way to keep the code readable.
--- arch/arm64/include/asm/processor.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
arch/arm64/include/asm/processor.h +12 -12
@@ -220,18 +220,6 @@ static inline void start_thread(struct pt_regs *regs, unsigned long pc, regs->sp = sp; } -static inline bool is_ttbr0_addr (unsigned long addr) -{ -/* entry assembly clears tags for TTBR0 addrs */ -return addr <TASK_SIZE ; -} - -static inline bool is_ttbr1_addr (unsigned long addr) -{ -/* TTBR1 addresses may have a tag if KASAN_SW_TAGS is in use */ -return arch_kasan_reset_tag (addr) >=PAGE_OFFSET ; -} -#ifdef CONFIG_COMPAT static inline void compat_start_thread (struct pt_regs *regs,unsigned long pc,unsigned long sp)
@@ -252,6 +240,18 @@ static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc, }#endif +static inline bool is_ttbr0_addr (unsigned long addr) +{ +/* entry assembly clears tags for TTBR0 addrs */ +return addr <TASK_SIZE ; +} + +static inline bool is_ttbr1_addr (unsigned long addr) +{ +/* TTBR1 addresses may have a tag if KASAN_SW_TAGS is in use */ +return arch_kasan_reset_tag (addr) >=PAGE_OFFSET ; +} +/* Forward declaration, a strange C thing */ struct task_struct ;
Signature · 7 lines
2.28.0.681.g6f77f65b4e-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerPATCH 12/19 arm64: Treat SSBS as a non-strict system feature
In reply to Will DeaconIf all CPUs discovered during boot have SSBS, then spectre-v4 will be considered to be "mitigated". However, we still allow late CPUs without SSBS to be onlined, albeit with a "SANITY CHECK" warning. This is problematic for userspace because it means that the system can quietly transition to "Vulnerable" at runtime.
Avoid this by treating SSBS as a non-strict system feature: if all of the CPUs discovered during boot have SSBS, then late arriving secondaries better have it as well.
--- arch/arm64/kernel/cpufeature.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm64/kernel/cpufeature.c +3 -3
@@ -227,7 +227,7 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = {ARM64_FTR_BITS (FTR_HIDDEN ,FTR_STRICT ,FTR_LOWER_SAFE ,ID_AA64PFR1_MPAMFRAC_SHIFT ,4 ,0 ),ARM64_FTR_BITS (FTR_HIDDEN ,FTR_STRICT ,FTR_LOWER_SAFE ,ID_AA64PFR1_RASFRAC_SHIFT ,4 ,0 ), -ARM64_FTR_BITS (FTR_VISIBLE ,FTR_STRICT ,FTR_LOWER_SAFE ,ID_AA64PFR1_SSBS_SHIFT ,4 ,ID_AA64PFR1_SSBS_PSTATE_NI ), +ARM64_FTR_BITS (FTR_VISIBLE ,FTR_NONSTRICT ,FTR_LOWER_SAFE ,ID_AA64PFR1_SSBS_SHIFT ,4 ,ID_AA64PFR1_SSBS_PSTATE_NI ),ARM64_FTR_BITS (FTR_VISIBLE_IF_IS_ENABLED (CONFIG_ARM64_BTI ),FTR_STRICT ,FTR_LOWER_SAFE ,ID_AA64PFR1_BT_SHIFT ,4 ,0 ),ARM64_FTR_END ,
@@ -487,7 +487,7 @@ static const struct arm64_ftr_bits ftr_id_pfr1[] = { };static const struct arm64_ftr_bits ftr_id_pfr2[] = { -ARM64_FTR_BITS (FTR_HIDDEN ,FTR_STRICT ,FTR_LOWER_SAFE ,ID_PFR2_SSBS_SHIFT ,4 ,0 ), +ARM64_FTR_BITS (FTR_HIDDEN ,FTR_NONSTRICT ,FTR_LOWER_SAFE ,ID_PFR2_SSBS_SHIFT ,4 ,0 ),ARM64_FTR_BITS (FTR_HIDDEN ,FTR_NONSTRICT ,FTR_LOWER_SAFE ,ID_PFR2_CSV3_SHIFT ,4 ,0 ),ARM64_FTR_END , };
@@ -1977,7 +1977,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = { { .desc = "Speculative Store Bypassing Safe (SSBS)", .capability = ARM64_SSBS, - .type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE, + .type = ARM64_CPUCAP_SYSTEM_FEATURE, .matches = has_cpuid_feature, .sys_reg = SYS_ID_AA64PFR1_EL1, .field_pos = ID_AA64PFR1_SSBS_SHIFT,
Signature · 7 lines
2.28.0.681.g6f77f65b4e-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerPATCH 13/19 arm64: Rename ARM64_SSBD to ARM64_SPECTRE_V4
In reply to Will DeaconIn a similar manner to the renaming of ARM64_HARDEN_BRANCH_PREDICTOR to ARM64_SPECTRE_V2, rename ARM64_SSBD to ARM64_SPECTRE_V4. This isn't _entirely_ accurate, as we also need to take into account the interaction with SSBS, but that will be taken care of in subsequent patches.
--- arch/arm64/include/asm/cpucaps.h | 2 +- arch/arm64/kernel/cpu_errata.c | 2 +- arch/arm64/kvm/hyp/include/hyp/switch.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
arch/arm64/include/asm/cpucaps.h +1 -1
@@ -37,7 +37,7 @@#define ARM64_HAS_CACHE_IDC 27#define ARM64_HAS_CACHE_DIC 28#define ARM64_HW_DBM 29 -#define ARM64_SSBD 30 +#define ARM64_SPECTRE_V4 30#define ARM64_MISMATCHED_CACHE_TYPE 31#define ARM64_HAS_STAGE2_FWB 32#define ARM64_HAS_CRC32 33
arch/arm64/kernel/cpu_errata.c +1 -1
@@ -675,7 +675,7 @@ const struct arm64_cpu_capabilities arm64_errata[] = {#endif { .desc = "Speculative Store Bypass Disable", - .capability = ARM64_SSBD, + .capability = ARM64_SPECTRE_V4, .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, .matches = has_ssbd_mitigation, .cpu_enable = cpu_enable_ssbd_mitigation,
arch/arm64/kvm/hyp/include/hyp/switch.h +1 -1
@@ -481,7 +481,7 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)static inline bool __needs_ssbd_off (struct kvm_vcpu *vcpu) { -if (!cpus_have_final_cap (ARM64_SSBD )) +if (!cpus_have_final_cap (ARM64_SPECTRE_V4 ))return false;return !(vcpu->arch.workaround_flags &VCPU_WORKAROUND_2_FLAG );
Signature · 7 lines
2.28.0.681.g6f77f65b4e-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerPATCH 14/19 arm64: Move SSBD prctl() handler alongside other spectre mitigation code
In reply to Will DeaconAs part of the spectre consolidation effort to shift all of the ghosts into their own proton pack, move all of the horrible SSBD prctl() code out of its own 'ssbd.c' file.
--- arch/arm64/kernel/Makefile | 2 +- arch/arm64/kernel/proton-pack.c | 118 +++++++++++++++++++++++++++++ arch/arm64/kernel/ssbd.c | 129 -------------------------------- 3 files changed, 119 insertions(+), 130 deletions(-) delete mode 100644 arch/arm64/kernel/ssbd.c
arch/arm64/kernel/Makefile +1 -1
@@ -19,7 +19,7 @@ obj-y := debug-monitors.o entry.o irq.o fpsimd.o \ return_address.o cpuinfo.o cpu_errata.o \ cpufeature.o alternative.o cacheinfo.o \ smp.o smp_spin_table.o topology.o smccc-call.o \ - ssbd.o syscall.o proton-pack.o + syscall.o proton-pack.o targets += efi-entry.o
arch/arm64/kernel/proton-pack.c +118 -0
127 lines not on this page · raw message
arch/arm64/kernel/ssbd.c deleted +0 -129
129 lines not on this page · raw message
Signature · 7 lines
2.28.0.681.g6f77f65b4e-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerPATCH 15/19 arm64: Rewrite Spectre-v4 mitigation code
In reply to Will DeaconRewrite the Spectre-v4 mitigation handling code to follow the same approach as that taken by Spectre-v2.
For now, report to KVM that the system is vulnerable (by forcing 'ssbd_state' to ARM64_SSBD_UNKNOWN), as this will be cleared up in subsequent steps.
--- arch/arm64/include/asm/processor.h | 19 +- arch/arm64/include/asm/spectre.h | 5 + arch/arm64/kernel/cpu_errata.c | 217 +------------- arch/arm64/kernel/cpufeature.c | 41 --- arch/arm64/kernel/entry.S | 6 +- arch/arm64/kernel/hibernate.c | 6 +- arch/arm64/kernel/process.c | 17 +- arch/arm64/kernel/proton-pack.c | 439 +++++++++++++++++++++++++---- arch/arm64/kernel/suspend.c | 3 +- 9 files changed, 401 insertions(+), 352 deletions(-)
arch/arm64/include/asm/processor.h +2 -17
@@ -198,25 +198,12 @@ static inline void start_thread_common(struct pt_regs *regs, unsigned long pc) regs->pmr_save =GIC_PRIO_IRQON ; } -static inline void set_ssbs_bit (struct pt_regs *regs) -{ - regs->pstate |=PSR_SSBS_BIT ; -} - -static inline void set_compat_ssbs_bit (struct pt_regs *regs) -{ - regs->pstate |=PSR_AA32_SSBS_BIT ; -} -static inline void start_thread (struct pt_regs *regs,unsigned long pc,unsigned long sp) {start_thread_common (regs, pc); regs->pstate = PSR_MODE_EL0t; - -if (arm64_get_ssbd_state () !=ARM64_SSBD_FORCE_ENABLE ) -set_ssbs_bit (regs); - +spectre_v4_enable_task_mitigation (current); regs->sp = sp; }
@@ -233,9 +220,7 @@ static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc, regs->pstate |=PSR_AA32_E_BIT ;#endif -if (arm64_get_ssbd_state () !=ARM64_SSBD_FORCE_ENABLE ) -set_compat_ssbs_bit (regs); - +spectre_v4_enable_task_mitigation (current); regs->compat_sp = sp; }#endif
arch/arm64/include/asm/spectre.h +5 -0
@@ -24,4 +24,9 @@ enum mitigation_state arm64_get_spectre_v2_state(void);bool has_spectre_v2 (const struct arm64_cpu_capabilities *cap,int scope);void spectre_v2_enable_mitigation (const struct arm64_cpu_capabilities *__unused); +enum mitigation_state arm64_get_spectre_v4_state (void ); +bool has_spectre_v4 (const struct arm64_cpu_capabilities *cap,int scope); +void spectre_v4_enable_mitigation (const struct arm64_cpu_capabilities *__unused); +void spectre_v4_enable_task_mitigation (struct task_struct *tsk); +#endif /* __ASM_SPECTRE_H */
arch/arm64/kernel/cpu_errata.c +4 -213
240 lines not on this page · raw message
arch/arm64/kernel/cpufeature.c +0 -41
53 lines not on this page · raw message
arch/arm64/kernel/entry.S +3 -3
@@ -132,8 +132,8 @@ alternative_else_nop_endif * them if required. */ .macro apply_ssbd, state, tmp1, tmp2 -alternative_cb arm64_enable_wa2_handling - b .L__asm_ssbd_skip\@ +alternative_cb spectre_v4_patch_fw_mitigation_enable + b .L__asm_ssbd_skip\@ // Patched to NOP alternative_cb_end ldr_this_cpu \tmp2, arm64_ssbd_callback_required, \tmp1 cbz \tmp2, .L__asm_ssbd_skip\@
@@ -141,7 +141,7 @@ alternative_cb_end tbnz \tmp2, #TIF_SSBD, .L__asm_ssbd_skip\@ mov w0, #ARM_SMCCC_ARCH_WORKAROUND_2 mov w1, #\state -alternative_cb arm64_update_smccc_conduit +alternative_cb spectre_v4_patch_fw_mitigation_conduit nop // Patched to SMC/HVC #0 alternative_cb_end .L__asm_ssbd_skip\@:
arch/arm64/kernel/hibernate.c +1 -5
@@ -332,11 +332,7 @@ int swsusp_arch_suspend(void)* mitigation off behind our back, let's set the state * to what we expect it to be. */ -switch (arm64_get_ssbd_state ()) { -case ARM64_SSBD_FORCE_ENABLE : -case ARM64_SSBD_KERNEL : -arm64_set_ssbd_mitigation (true); - } +spectre_v4_enable_mitigation (NULL ); }local_daif_restore (flags);
arch/arm64/kernel/process.c +3 -14
@@ -421,8 +421,7 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start, cpus_have_const_cap(ARM64_HAS_UAO)) childregs->pstate |=PSR_UAO_BIT ; -if (arm64_get_ssbd_state () ==ARM64_SSBD_FORCE_DISABLE ) -set_ssbs_bit (childregs); +spectre_v4_enable_task_mitigation (p);if (system_uses_irq_prio_masking ()) childregs->pmr_save =GIC_PRIO_IRQON ;
@@ -472,8 +471,6 @@ void uao_thread_switch(struct task_struct *next)*/ static void ssbs_thread_switch (struct task_struct *next) { -struct pt_regs *regs =task_pt_regs (next); -/* * Nothing to do for kernel threads, but 'regs' may be junk * (e.g. idle task) so check the flags and bail early.
@@ -485,18 +482,10 @@ static void ssbs_thread_switch(struct task_struct *next)* If all CPUs implement the SSBS extension, then we just need to * context-switch the PSTATE field. */ -if (cpu_have_feature (cpu_feature (SSBS ))) -return ; - -/* If the mitigation is enabled, then we leave SSBS clear. */ -if ((arm64_get_ssbd_state () ==ARM64_SSBD_FORCE_ENABLE ) || -test_tsk_thread_flag (next,TIF_SSBD )) +if (cpus_have_const_cap (ARM64_SSBS ))return ; -if (compat_user_mode (regs)) -set_compat_ssbs_bit (regs); -else if (user_mode (regs)) -set_ssbs_bit (regs); +spectre_v4_enable_task_mitigation (next); }/*
arch/arm64/kernel/proton-pack.c +382 -57
483 lines not on this page · raw message
arch/arm64/kernel/suspend.c +1 -2
@@ -72,8 +72,7 @@ void notrace __cpu_suspend_exit(void)* have turned the mitigation on. If the user has forcefully * disabled it, make sure their wishes are obeyed. */ -if (arm64_get_ssbd_state () ==ARM64_SSBD_FORCE_DISABLE ) -arm64_set_ssbd_mitigation (false); +spectre_v4_enable_mitigation (NULL ); }/*
Signature · 7 lines
2.28.0.681.g6f77f65b4e-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerPATCH 16/19 KVM: arm64: Simplify handling of ARCH_WORKAROUND_2
In reply to Will DeaconFrom: Marc Zyngier <[email protected]>
Owing to the fact that the host kernel is always mitigated, we can drastically simplify the WA2 handling by keeping the mitigation state ON when entering the guest. This means the guest is either unaffected or not mitigated.
This results in a nice simplification of the mitigation space, and the removal of a lot of code that was never really used anyway.
--- arch/arm64/include/asm/kvm_asm.h | 3 -- arch/arm64/include/asm/kvm_emulate.h | 14 ------ arch/arm64/include/asm/kvm_mmu.h | 17 ------- arch/arm64/include/uapi/asm/kvm.h | 9 ++++ arch/arm64/kernel/cpu_errata.c | 14 ------ arch/arm64/kernel/image-vars.h | 2 - arch/arm64/kvm/arm.c | 4 -- arch/arm64/kvm/hyp/hyp-entry.S | 27 ----------- arch/arm64/kvm/hyp/include/hyp/switch.h | 29 ------------ arch/arm64/kvm/hyp/nvhe/switch.c | 4 -- arch/arm64/kvm/hyp/vhe/switch.c | 4 -- arch/arm64/kvm/hypercalls.c | 14 +++--- arch/arm64/kvm/psci.c | 59 +++++++++++-------------- arch/arm64/kvm/reset.c | 4 -- 14 files changed, 41 insertions(+), 163 deletions(-)
arch/arm64/include/asm/kvm_asm.h +0 -3
@@ -9,9 +9,6 @@#include <asm/virt.h> -#define VCPU_WORKAROUND_2_FLAG_SHIFT 0 -#define VCPU_WORKAROUND_2_FLAG (_AC(1, UL) << VCPU_WORKAROUND_2_FLAG_SHIFT) -#define ARM_EXIT_WITH_SERROR_BIT 31#define ARM_EXCEPTION_CODE (x) ((x) & ~(1U << ARM_EXIT_WITH_SERROR_BIT))#define ARM_EXCEPTION_IS_TRAP (x) (ARM_EXCEPTION_CODE((x)) == ARM_EXCEPTION_TRAP)
arch/arm64/include/asm/kvm_emulate.h +0 -14
@@ -383,20 +383,6 @@ static inline unsigned long kvm_vcpu_get_mpidr_aff(struct kvm_vcpu *vcpu)return vcpu_read_sys_reg (vcpu,MPIDR_EL1 ) &MPIDR_HWID_BITMASK ; } -static inline bool kvm_arm_get_vcpu_workaround_2_flag (struct kvm_vcpu *vcpu) -{ -return vcpu->arch.workaround_flags &VCPU_WORKAROUND_2_FLAG ; -} - -static inline void kvm_arm_set_vcpu_workaround_2_flag (struct kvm_vcpu *vcpu, -bool flag) -{ -if (flag) - vcpu->arch.workaround_flags |=VCPU_WORKAROUND_2_FLAG ; -else - vcpu->arch.workaround_flags &= ~VCPU_WORKAROUND_2_FLAG ; -} -static inline void kvm_vcpu_set_be (struct kvm_vcpu *vcpu) {if (vcpu_mode_is_32bit (vcpu)) {
arch/arm64/include/asm/kvm_mmu.h +0 -17
@@ -526,23 +526,6 @@ static inline int kvm_map_vectors(void) }#endif -DECLARE_PER_CPU_READ_MOSTLY (u64, arm64_ssbd_callback_required); - -static inline int hyp_map_aux_data (void ) -{ -int cpu, err; - -for_each_possible_cpu (cpu) { -u64 *ptr; - - ptr =per_cpu_ptr (&arm64_ssbd_callback_required, cpu); - err =create_hyp_mappings (ptr, ptr +1 ,PAGE_HYP ); -if (err) -return err; - } -return 0 ; -} -#define kvm_phys_to_vttbr (addr) phys_to_ttbr(addr)/*
arch/arm64/include/uapi/asm/kvm.h +9 -0
@@ -242,6 +242,15 @@ struct kvm_vcpu_events {#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL 0#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_AVAIL 1#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_REQUIRED 2 + +/* +* Only two states can be presented by the host kernel: +* - NOT_REQUIRED: the guest doesn't need to do anything +* - NOT_AVAIL: the guest isn't mitigated (it can still use SSBS if available) +* +* All the other values are deprecated. The host still accepts all +* values (they are ABI), but will narrow them to the above two. +*/ #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2 KVM_REG_ARM_FW_REG(2)#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL 0#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_UNKNOWN 1
arch/arm64/kernel/cpu_errata.c +0 -14
@@ -108,20 +108,6 @@ cpu_enable_trap_ctr_access(const struct arm64_cpu_capabilities *cap)int ssbd_state__read_mostly =ARM64_SSBD_UNKNOWN ; -void __init arm64_enable_wa2_handling (struct alt_instr *alt, -__le32 *origptr,__le32 *updptr, -int nr_inst) -{ -BUG_ON (nr_inst !=1 ); -/* -* Only allow mitigation on EL1 entry/exit and guest -* ARCH_WORKAROUND_2 handling if the SSBD state allows it to -* be flipped. -*/ -if (arm64_get_ssbd_state () ==ARM64_SSBD_KERNEL ) - *updptr =cpu_to_le32 (aarch64_insn_gen_nop ()); -} -#ifdef CONFIG_ARM64_ERRATUM_1463225 DEFINE_PER_CPU (int, __in_cortex_a76_erratum_1463225_wa);
arch/arm64/kernel/image-vars.h +0 -2
@@ -64,12 +64,10 @@ __efistub__ctype = _ctype;#define KVM_NVHE_ALIAS (sym) __kvm_nvhe_##sym = sym;/* Alternative callbacks for init-time patching of nVHE hyp code. */ -KVM_NVHE_ALIAS (arm64_enable_wa2_handling);KVM_NVHE_ALIAS (kvm_patch_vector_branch);KVM_NVHE_ALIAS (kvm_update_va_mask);/* Global kernel state accessed by nVHE hyp code. */ -KVM_NVHE_ALIAS (arm64_ssbd_callback_required);KVM_NVHE_ALIAS (kvm_host_data);KVM_NVHE_ALIAS (kvm_vgic_global_state);
arch/arm64/kvm/arm.c +0 -4
@@ -1552,10 +1552,6 @@ static int init_hyp_mode(void) } } - err =hyp_map_aux_data (); -if (err) -kvm_err ("Cannot map host auxiliary data: %d\n" , err); -return 0 ; out_err:
arch/arm64/kvm/hyp/hyp-entry.S +0 -27
@@ -116,33 +116,6 @@ el1_hvc_guest: ARM_SMCCC_ARCH_WORKAROUND_2) cbnz w1, el1_trap -alternative_cb arm64_enable_wa2_handling - b wa2_end -alternative_cb_end - get_vcpu_ptr x2, x0 - ldr x0, [x2, #VCPU_WORKAROUND_FLAGS] - - // Sanitize the argument and update the guest flags - ldr x1, [sp, #8] // Guest's x1 - clz w1, w1 // Murphy's device: - lsr w1, w1, #5 // w1 = !!w1 without using - eor w1, w1, #1 // the flags... - bfi x0, x1, #VCPU_WORKAROUND_2_FLAG_SHIFT, #1 - str x0, [x2, #VCPU_WORKAROUND_FLAGS] - - /* Check that we actually need to perform the call */ - hyp_ldr_this_cpu x0, arm64_ssbd_callback_required, x2 - cbz x0, wa2_end - - mov w0, #ARM_SMCCC_ARCH_WORKAROUND_2 - smc #0 - - /* Don't leak data from the SMC call */ - mov x3, xzr -wa2_end: - mov x2, xzr - mov x1, xzr - wa_epilogue: mov x0, xzr add sp, sp, #16
arch/arm64/kvm/hyp/include/hyp/switch.h +0 -29
@@ -479,35 +479,6 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)return false; } -static inline bool __needs_ssbd_off (struct kvm_vcpu *vcpu) -{ -if (!cpus_have_final_cap (ARM64_SPECTRE_V4 )) -return false; - -return !(vcpu->arch.workaround_flags &VCPU_WORKAROUND_2_FLAG ); -} - -static inline void __set_guest_arch_workaround_state (struct kvm_vcpu *vcpu) -{ -/* -* The host runs with the workaround always present. If the -* guest wants it disabled, so be it... -*/ -if (__needs_ssbd_off (vcpu) && -__hyp_this_cpu_read (arm64_ssbd_callback_required)) -arm_smccc_1_1_smc (ARM_SMCCC_ARCH_WORKAROUND_2 ,0 ,NULL ); -} - -static inline void __set_host_arch_workaround_state (struct kvm_vcpu *vcpu) -{ -/* -* If the guest has disabled the workaround, bring it back on. -*/ -if (__needs_ssbd_off (vcpu) && -__hyp_this_cpu_read (arm64_ssbd_callback_required)) -arm_smccc_1_1_smc (ARM_SMCCC_ARCH_WORKAROUND_2 ,1 ,NULL ); -} -static inline void __kvm_unexpected_el2_exception (void ) {unsigned long addr, fixup;
arch/arm64/kvm/hyp/nvhe/switch.c +0 -4
@@ -202,8 +202,6 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)__debug_switch_to_guest (vcpu); -__set_guest_arch_workaround_state (vcpu); - do { /* Jump in the fire! */ exit_code = __guest_enter(vcpu, host_ctxt);
@@ -211,8 +209,6 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)/* And we're baaack! */ }while (fixup_guest_exit (vcpu, &exit_code)); -__set_host_arch_workaround_state (vcpu); -__sysreg_save_state_nvhe (guest_ctxt);__sysreg32_save_state (vcpu);__timer_disable_traps (vcpu);
arch/arm64/kvm/hyp/vhe/switch.c +0 -4
@@ -131,8 +131,6 @@ static int __kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)sysreg_restore_guest_state_vhe (guest_ctxt);__debug_switch_to_guest (vcpu); -__set_guest_arch_workaround_state (vcpu); - do { /* Jump in the fire! */ exit_code = __guest_enter(vcpu, host_ctxt);
@@ -140,8 +138,6 @@ static int __kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)/* And we're baaack! */ }while (fixup_guest_exit (vcpu, &exit_code)); -__set_host_arch_workaround_state (vcpu); -sysreg_save_guest_state_vhe (guest_ctxt);__deactivate_traps (vcpu);
arch/arm64/kvm/hypercalls.c +6 -8
@@ -36,15 +36,13 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) }break ;case ARM_SMCCC_ARCH_WORKAROUND_2 : -switch (kvm_arm_have_ssbd ()) { -case KVM_SSBD_FORCE_DISABLE : -case KVM_SSBD_UNKNOWN : +switch (arm64_get_ssbd_state ()) { +case ARM64_SSBD_FORCE_DISABLE : +case ARM64_SSBD_UNKNOWN :break ; -case KVM_SSBD_KERNEL : - val =SMCCC_RET_SUCCESS ; -break ; -case KVM_SSBD_FORCE_ENABLE : -case KVM_SSBD_MITIGATED : +case ARM64_SSBD_KERNEL : +case ARM64_SSBD_FORCE_ENABLE : +case ARM64_SSBD_MITIGATED : val =SMCCC_RET_NOT_REQUIRED ;break ; }
arch/arm64/kvm/psci.c +26 -33
91 lines not on this page · raw message
arch/arm64/kvm/reset.c +0 -4
@@ -319,10 +319,6 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) vcpu->arch.reset_state.reset = false; } -/* Default workaround setup is enabled (if supported) */ -if (kvm_arm_have_ssbd () ==KVM_SSBD_KERNEL ) - vcpu->arch.workaround_flags |=VCPU_WORKAROUND_2_FLAG ; -/* Reset timer */ ret =kvm_timer_vcpu_reset (vcpu); out:
Signature · 7 lines
2.28.0.681.g6f77f65b4e-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerPATCH 17/19 KVM: arm64: Get rid of kvm_arm_have_ssbd()
In reply to Will DeaconFrom: Marc Zyngier <[email protected]>
kvm_arm_have_ssbd() is now completely unused, get rid of it.
--- arch/arm64/include/asm/kvm_host.h | 23 ----------------------- 1 file changed, 23 deletions(-)
arch/arm64/include/asm/kvm_host.h +0 -23
@@ -631,29 +631,6 @@ static inline void kvm_set_pmu_events(u32 set, struct perf_event_attr *attr) {}static inline void kvm_clr_pmu_events (u32 clr) {}#endif -#define KVM_SSBD_UNKNOWN -1 -#define KVM_SSBD_FORCE_DISABLE 0 -#define KVM_SSBD_KERNEL 1 -#define KVM_SSBD_FORCE_ENABLE 2 -#define KVM_SSBD_MITIGATED 3 - -static inline int kvm_arm_have_ssbd (void ) -{ -switch (arm64_get_ssbd_state ()) { -case ARM64_SSBD_FORCE_DISABLE : -return KVM_SSBD_FORCE_DISABLE ; -case ARM64_SSBD_KERNEL : -return KVM_SSBD_KERNEL ; -case ARM64_SSBD_FORCE_ENABLE : -return KVM_SSBD_FORCE_ENABLE ; -case ARM64_SSBD_MITIGATED : -return KVM_SSBD_MITIGATED ; -case ARM64_SSBD_UNKNOWN : -default : -return KVM_SSBD_UNKNOWN ; - } -} -void kvm_vcpu_load_sysregs_vhe (struct kvm_vcpu *vcpu);void kvm_vcpu_put_sysregs_vhe (struct kvm_vcpu *vcpu);
Signature · 7 lines
2.28.0.681.g6f77f65b4e-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerPATCH 18/19 KVM: arm64: Convert ARCH_WORKAROUND_2 to arm64_get_spectre_v4_state()
In reply to Will DeaconFrom: Marc Zyngier <[email protected]>
Convert the KVM WA2 code to using the Spectre infrastructure, making the code much more readable. It also allows us to take SSBS into account for the mitigation.
--- arch/arm64/kvm/arm.c | 2 +- arch/arm64/kvm/hypercalls.c | 23 +++++++++++++++++------ arch/arm64/kvm/psci.c | 19 ++++++++++++------- 3 files changed, 30 insertions(+), 14 deletions(-)
arch/arm64/kvm/arm.c +1 -1
@@ -1295,7 +1295,7 @@ static void cpu_init_hyp_mode(void)* at EL2. */ if (this_cpu_has_cap (ARM64_SSBS ) && -arm64_get_ssbd_state () ==ARM64_SSBD_FORCE_DISABLE ) { +arm64_get_spectre_v4_state () ==SPECTRE_VULNERABLE ) {kvm_call_hyp_nvhe (__kvm_enable_ssbs); } }
arch/arm64/kvm/hypercalls.c +17 -6
@@ -36,13 +36,24 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) }break ;case ARM_SMCCC_ARCH_WORKAROUND_2 : -switch (arm64_get_ssbd_state ()) { -case ARM64_SSBD_FORCE_DISABLE : -case ARM64_SSBD_UNKNOWN : +switch (arm64_get_spectre_v4_state ()) { +case SPECTRE_VULNERABLE :break ; -case ARM64_SSBD_KERNEL : -case ARM64_SSBD_FORCE_ENABLE : -case ARM64_SSBD_MITIGATED : +case SPECTRE_MITIGATED : +/* +* SSBS everywhere: Indicate no firmware +* support, as the SSBS support will be +* indicated to the guest and the default is +* safe. +* +* Otherwise, expose a permanent mitigation +* to the guest, and hide SSBS so that the +* guest stays protected. +*/ +if (cpus_have_final_cap (ARM64_SSBS )) +break ; + fallthrough; +case SPECTRE_UNAFFECTED : val =SMCCC_RET_NOT_REQUIRED ;break ; }
arch/arm64/kvm/psci.c +12 -7
@@ -435,14 +435,19 @@ static int get_kernel_wa_level(u64 regid) }return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL ;case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2 : -switch (arm64_get_ssbd_state ()) { -case ARM64_SSBD_FORCE_ENABLE : -case ARM64_SSBD_MITIGATED : -case ARM64_SSBD_KERNEL : +switch (arm64_get_spectre_v4_state ()) { +case SPECTRE_MITIGATED : +/* +* As for the hypercall discovery, we pretend we +* don't have any FW mitigation if SSBS is there at +* all times. +*/ +if (cpus_have_final_cap (ARM64_SSBS )) +return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL ; + fallthrough; +case SPECTRE_UNAFFECTED :return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED ; -case ARM64_SSBD_UNKNOWN : -case ARM64_SSBD_FORCE_DISABLE : -default : +case SPECTRE_VULNERABLE :return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL ; } }
Signature · 7 lines
2.28.0.681.g6f77f65b4e-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerPATCH 19/19 arm64: Get rid of arm64_ssbd_state
In reply to Will DeaconFrom: Marc Zyngier <[email protected]>
Out with the old ghost, in with the new...
--- arch/arm64/include/asm/cpufeature.h | 14 -------------- arch/arm64/kernel/cpu_errata.c | 2 -- 2 files changed, 16 deletions(-)
arch/arm64/include/asm/cpufeature.h +0 -14
@@ -698,20 +698,6 @@ static inline bool system_supports_tlb_range(void)cpus_have_const_cap (ARM64_HAS_TLB_RANGE ); } -#define ARM64_SSBD_UNKNOWN -1 -#define ARM64_SSBD_FORCE_DISABLE 0 -#define ARM64_SSBD_KERNEL 1 -#define ARM64_SSBD_FORCE_ENABLE 2 -#define ARM64_SSBD_MITIGATED 3 - -static inline int arm64_get_ssbd_state (void ) -{ -extern int ssbd_state; -return ssbd_state; -} - -void arm64_set_ssbd_mitigation (bool state); -extern int do_emulate_mrs (struct pt_regs *regs,u32 sys_reg,u32 rt);static inline u32 id_aa64mmfr0_parange_to_phys_shift (int parange)
arch/arm64/kernel/cpu_errata.c +0 -2
@@ -106,8 +106,6 @@ cpu_enable_trap_ctr_access(const struct arm64_cpu_capabilities *cap)sysreg_clear_set (sctlr_el1,SCTLR_EL1_UCT ,0 ); } -int ssbd_state__read_mostly =ARM64_SSBD_UNKNOWN ; -#ifdef CONFIG_ARM64_ERRATUM_1463225 DEFINE_PER_CPU (int, __in_cortex_a76_erratum_1463225_wa);
Signature · 7 lines
2.28.0.681.g6f77f65b4e-goog _______________________________________________ linux-arm-kernel mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon
maintainerOn the off-chance that anybody's reading this...
Quoted 11 lines · Will Deacon
The temptation was to remove the code entirely, but after putting in some effort to untangle it, we ended up knocking it into a much better shape. Although that doesn't change the fact that we can't test it very well, it certainly appears to behave better than the old code in situations such as:
- Err... wanting mitigation on more than one CPU
- Not changing the mitigation state at runtime (i.e. after userspace has started running)
Quoted 8 lines
- Gracefully handling failure to bring late CPUs online (previously this would only happen _after_ updating the mitigation state!)
- Clear separation between mitigation state (am I vulnerable?) and policy (the user wants to go fast)
- Removal of the hideously expensive "dynamic" Spectre-v2 mitigation for KVM guests
^^^ This should be 'hideously expensive "dynamic" Spectre-v4 mitigation'. The firmware call itself is helpfully named "workaround 2", so I always get them mixed up.
Will
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel